[Bug]: Backend startup crashes leave desktop blank with no visible error#10517

openedSep 7, 2026byCchrisdeeming

Before submitting

  • I searched existing issues and did not find a duplicate of this specific failure.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/desktop

Steps to reproduce

  1. Launch desktop with a backend that fails during startup (observed: a missing SQLite column).
  2. The backend exits repeatedly before it can serve the renderer.

Expected behavior

Show a backend-independent startup error with the failure reason and a way to retry or open/copy logs.

Actual behavior

Completely black window. Electron DevTools has no useful error; Network shows a failed t3code://app request. Restarting/reinstalling does not explain the failure.

Production serves the initial UI through the backend. DesktopWindow.ts swallows loadURL() rejection and only logs did-fail-load; backend restart handling keeps retrying without a visible terminal failure state. Frontend error handling cannot run because the page never loads.

Related: #9239 reports a Linux credential-store startup stall; this is a confirmed backend process crash on macOS.

Impact

Blocks work completely

Version or commit

0.0.39 and 0.0.40-nightly.20260907.1346

Environment

macOS 26.6.2 (also occurred before the macOS update), Electron desktop.

Logs or stack traces

text
1Error: no such column: branch_pull_request_json
2backend child exits with code=1
3ECONNREFUSED 127.0.0.1:3773

The database error is a separate cause; this issue concerns the absence of visible diagnostics when startup fails.

Triage

Confirmed. This is a real desktop bug: when the local backend child dies before (or while) serving the renderer, production shows a blank window and never surfaces the failure.

This is not a duplicate of #9239. That issue is a Linux credential-store stall. This report is a confirmed backend process crash on macOS (code=1, ECONNREFUSED), with a failed t3code://app load.

What the code does today

Production serves the first UI through the backend (t3code:// → backend in apps/desktop/src/electron/ElectronProtocol.ts). The main window is created after HTTP readiness, then loadURL("t3code://app/").

In DesktopWindow.ts:

  • loadURL() rejection is swallowed (catch(() => undefined)).
  • did-fail-load only logs.
  • Automatic reload retries are development-only.
  • The connecting splash is a backend-independent data URL, but it is WSL-only.

In DesktopBackendManager.ts, an unexpected child exit schedules an unbounded restart (backend exited unexpectedly; restart scheduled). The existing terminal UI (onPreflightFailed / showErrorBox) covers WSL preflight and Electron-main bootstrap only — not a crash-looping primary child. handleBackendNotReady clears a latch; it does not replace the blank page.

Frontend error handling cannot run because the page never loads. The child reason is already written to server-child.log; the window never shows it.

Related

  • #9239 / #9246 — same blank-window symptom, different cause.
  • #3513 — sticky error after the renderer loads; opposite gap.
  • #8896 / #9312 — persistence/migration crash-loops (including no such column) that leave desktop without a usable window. Related trigger class.
  • #10101 — added branch_pull_request_json, the column in these logs.

The missing-column crash is a separate cause (likely another skipped/unapplied projection migration). This issue should stay scoped to the missing startup diagnostics.

Suggested fix

Add a main-process, backend-independent terminal failure surface (data-URL page like the WSL splash, or a dialog with Open/Copy logs) when:

  1. production main-frame t3code://app fails, or
  2. the primary child crash-loops past a bound without staying ready.

Show the last child error, plus Retry and Open/Copy logs. Do not rely on the web error boundary for this path.

Synced from GitHub

Adding a confirmed macOS reproduction on 0.0.45 and a source review of the v0.1.0 release tag. The desktop failure matches this issue, so I am adding the evidence here. The 0.1.0 findings below are code-based; I have not run 0.1.0 against the unrepaired database.

On macOS 27.0.1, build 26A434, Apple Silicon, the installed 0.0.45 app remained running but never displayed its main window. The backend child repeatedly exited with code 1. The application signature verified successfully. Its server-child log contained:

text
1PersistenceSqlError: SQL error in ProjectionSnapshotQuery.getCommandReadModel:listThreads:query: SQLITE(1) SQL logic error
2[cause]: Error: no such column: pin_order_key

The database's highest recorded migration ID was 54, but its schema and migration history disagreed with the installed build:

IDRecorded migration nameExpected by 0.0.45Actual schema
38ProjectionThreadHtmlPresentationProjectionThreadsPinOrderKeyprojection_threads.pin_order_key absent

The earlier build that introduced that entry has not been identified. This does not establish that an ordinary upgrade between official stable releases created the mismatch.

After stopping the app and verifying a backup, applying the missing column change from the bundled migration and reconciling the journal entry restored startup. The repair was validated on a database copy first. Integrity checks passed, every table's row count was preserved, and relaunching displayed the working window.

The generalized trigger is a migration history that causes a required schema change to be skipped, combined with startup code that needs the missing schema. The migrator skips IDs at or below the highest recorded ID, so even an absent intermediate journal entry can be skipped. Conflicting names alone need not cause a failure if the schema still satisfies the running code. Sharing a database between incompatible development, fork, nightly, or release histories can introduce the problem; using a nightly alone does not establish that condition.

The v0.1.0 tag adds safeguards, but several relevant paths remain:

This keeps the desktop request scoped to a backend-independent startup failure UI and bounded handling of a persistently failing primary child. Targeted schema repair is a separate concern. Regression coverage should include a journal/schema mismatch with a required column actually absent, plus the desktop response when the backend never reaches its first readiness state.

Related existing reports:

AI-assisted local investigation and tagged-source review using Codex.