Skip to content

Force-quitting an app an agent launched on macOS kills the desktop's renderer and backend, and the reloaded window never retries #26604

Open

Description

@OfficiallySp

What happened

A Claude agent in the desktop app built a GUI app and launched it. The app hung, and the user force-quit it. Each time, the T3 Code window went blank and came back as a fatal error screen:

PrimaryEnvironmentRequestError
Caused by: HttpClientError
Caused by: TypeError: Failed to fetch

The window only recovered when the user clicked Reload. This happened three times in five minutes (18:46:50, 18:50:33 and 18:51:53 UTC). Each time, every running Claude session was killed mid-turn (Claude Code process exited with code 143). That included a long-running workflow in another thread.

Diagnosis

This is two problems in a chain.

1. macOS kills T3 Code's processes along with the agent's app. The agent started the app by running its binary directly (App.app/Contents/MacOS/App) from Bash. The app was therefore a descendant of T3 Code. macOS attributes it to T3 Code: tccd logged responsible={identifier=com.t3tools.t3code, ...}, and LaunchServices reported it in T3 Code's coalition (17603). Force-quitting the app with ⌥⌘Esc, or toggling its entry under System Settings → Login Items, makes LaunchServices terminate T3 Code's processes in that coalition:

  • the renderer (render-process-gone, reason killed, exit 15)
  • the GPU, network and audio helpers
  • the backend, which exits 130 through Effect runMain, along with every Claude child

Only the Electron main process survived.

In the first occurrence, the app had its own coalition, so a different path did the damage. A Dock Force Quit made LaunchServices also kill a "subordinate non-foreground non-visible application", osascript (pid 61239). That process started 2 s after the desktop main process and ran for 28 minutes. It was most likely the desktop's own modifier-key poller (apps/desktop/src/snapShot/MacModifierPairShortcutProcess.ts). T3 Code's coalition went down right after, and no osascript was running afterwards. We did not find documentation of which processes LaunchServices includes.

A possible direction, not verified: spawn provider sessions so that macOS does not attribute their child apps to T3 Code, for example by disclaiming responsibility at spawn time.

2. The reloaded window does not wait for the backend and never retries.

  • render-process-gone with reason killed reloads after 500 ms (apps/desktop/src/window/DesktopWindow.ts:769-798, RENDERER_RECOVERY_RELOAD_DELAY_MS = 500). The desktop only noticed the backend had exited 3.7 s after the kill. It restarted the backend at +4.2 s, and the backend was ready at +5.1 s.
  • The reloaded route's beforeLoad failed straight away. PrimaryEnvironmentRequestError.fromCause maps a transport error with no response to status: 500 (apps/web/src/environments/primary/auth.ts:54). retryTransientBootstrap retries a TypeError (auth.ts:294-305), but it only ever sees the wrapped error, because fetchSessionState and fetchPrimaryEnvironmentDescriptor (context.ts:12-27) wrap inside the retried operation. 500 is not in {502, 503, 504}, so "backend not listening yet" is thrown on the first attempt.
  • handleBackendReady does not reload a window that is already showing the error screen.

These files have not changed for this on main (238 commits past v0.1.3).

Steps to reproduce

Reconstructed from three occurrences with the same sequence. It was not reproduced deliberately.

  1. macOS, T3 Code desktop 0.1.3 with its built-in local backend.
  2. In a Claude thread, have the agent build any GUI .app and run its binary directly from Bash, for example ./build/App.app/Contents/MacOS/App &.
  3. Force-quit that app with ⌥⌘Esc or Dock → Force Quit.
  4. Expected: only that app quits.
  5. Actual: the T3 Code window goes blank and reloads into the PrimaryEnvironmentRequestError / Failed to fetch screen, and running agent turns fail with exit 143. The backend comes back about 5 s later, but the window stays on the error screen until Reload.

Version

0.1.3 (T3 Code (Beta) desktop, stable)

Environment

macOS 27.0.1 (26A434), arm64; Claude Code 2.1.312

Evidence

# Crash 2, macOS unified log
18:50:33.336 LoginItems             sendAction                     # click in System Settings → Login Items
18:50:33.338 loginwindow            forceQuitAppURLFromBTM: ... terminating applications running because of a notification from BTM
18:50:33.346 loginwindow            _LSForceQuitApplication: asn=... "<app>" (96611) appPID=96611 coalition=17603
18:50:33.366 mDNSResponder          DNSServiceCreateConnection STOP PID[<network helper>](T3 Code (Beta) )
18:50:33.372 runningboardd          [anon<T3 Code (Beta) Helper>(501):<gpu pid>] termination reported by proc_exit
18:50:33.476 runningboardd          Removing process: <private> from coalition: <private> with coalitionID: 17603
# How the app was attributed when the agent launched it
18:49:16.118 tccd                   AUTHREQ_ATTRIBUTION: ... responsible={TCCDProcess: identifier=com.t3tools.t3code, ...}

# Crash 1, Dock Force Quit; the app was in its own coalition
18:46:50.208 Dock                   _LSForceQuitApplication: asn=... "<app>" (86681) appPID=86681 coalition=25762
18:46:50.244 Dock                   _LSForceQuitApplication: ... killing subordinate non-foreground non-visible application ... "osascript" (61239)
18:46:50.350 runningboardd          Removing process: <private> from coalition: <private> with coalitionID: 17603

# renderer-history.ndjson (main pid unchanged throughout)
18:46:50.361 render-process-gone reason=killed exitCode=15
18:46:51.090 dom-ready (new renderer)
18:50:33.529 render-process-gone reason=killed exitCode=15
18:50:34.338 dom-ready
18:51:01.187 dom-ready             # user clicked Reload

# desktop.trace.ndjson, crash 1
18:46:50.336 desktop.window.dispatchSnapShotEvent {event: "failed"}
18:46:54.041 desktop.backendInstance.scheduleRestartFiber  "backend exited unexpectedly; restart scheduled"
18:46:54.568 GET /.well-known/t3/environment  (connection refused x5, then 503 x3)
18:46:55.448 desktop.window.handleBackendReady  "backend ready"

# server-child.log
[18:46:50.597] WARN orchestration-v2.claude-query-stream-failed ... [cause]: Error: Claude Code process exited with code 143
[18:46:51.172] INFO V2 orchestration shutdown reconciliation completed { terminalizedRuns: 1, ... }
backend child process failure output end  details: pid=61242 code=130
backend child process failure output end  details: pid=87612 code=130

Related issues

#23378 shows the same fatal screen and names the same ?? 500 status mapping. Its trigger is different: a slow backend running out the desktop bearer-token retry budget. Here the backend was killed from outside and was down for about 5 s, and the web retry loop never retries a transport failure at all. #10517 (backend startup crashes leave the desktop blank) and #22247 (an OOM in a child process) have different causes.

Fix applied or workaround

Nothing was changed on the machine. Workaround: quit agent-launched apps normally (⌘Q), or with pkill -x <App> from a terminal, instead of Force Quit or the Login Items switch.

Filed by

Claude Code (claude-opus-5-5) via t3 triage

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions