Remote Control: session permanently wedged when worker dies unregistered (phantom worker_status:running); still reproduces on 2.1.259 (re-file of #76530)
Summary
Re-filing #76530, which the stale bot closed on 2026-09-03 without any maintainer response. The bug is unchanged and still reproduces on current CLI 2.1.259 (Windows 11, Desktop 1.40609.1, iOS app).
When a Remote Control worker dies without deregistering (crash, hard kill, power loss, Desktop app exit) while a turn is in flight, the session is left phantom server-side: worker_status: "running" + connection_status: "disconnected", indefinitely (observed 3+ hours, no TTL). New prompts from the mobile app are accepted as events but never dispatched to a new worker. The card spins forever. Stop + reprompt does nothing. Restarting the claude remote-control daemon revives cleanly-disconnected sessions but not this one.
Full repro, dead-end matrix, and root cause are in #76530 and still accurate. Short version of the root cause: worker_status is entirely client-authored (PUT {sdkUrl}/worker), so when the worker dies without writing a terminal state nothing server-side ever reconciles it against the dead transport, and dispatch keeps treating the session as served.
Related: #37321 (closed not planned), #60790, #52860.
New evidence since the original report
I run a local supervisor that polls my own sessions and detects this exact signature (worker_status=running + connection_status=disconnected). Since filing on 2026-07-10 it has caught and recovered 15 phantom sessions across 7 separate days, most recently 2026-08-28:
2026-08-17 16:19:53 phantom detected: cse_01S4EFQx3xQhTeqCuiuzjm6m (worker_status=running, disconnected) -> reviving
2026-08-25 17:36:49 phantom cse_01XhCYU8R5wow1ppcpQsRaVV: revived via bridge epoch 2
2026-08-25 17:36:50 phantom cse_01FkrcJHpn2X8HiFGd4qpMBB: revived via bridge epoch 2
... (5 more the same minute; one Desktop app exit orphaned 7 sessions at once)
2026-08-28 13:50:26 phantom cse_012MNrvRhMNrGWtahcGbWAq7: revived via bridge epoch 2
The common trigger is mundane: the Desktop app exits or crashes and takes the worker processes with it. No exotic kill needed. Every Desktop death with in-flight turns produces phantoms.
Recovery that works (still undocumented)
The epoch takeover already exists in the client; it is just not exposed. This is what the supervisor automates:
POST /v1/code/sessions/<id>/bridge(OAuth bearer,anthropic-version: 2023-06-01,anthropic-beta: ccr-byoc-2025-07-29, body{}) returns{worker_jwt, worker_epoch, ...}. The fresh epoch supersedes the phantom.- Spawn a worker with the JWT via env vars, the same way the daemon does:
CLAUDE_CODE_SESSION_ACCESS_TOKEN=<worker_jwt>,CLAUDE_CODE_WORKER_EPOCH=<epoch>,CLAUDE_CODE_SESSION_ID=<new-guid>,CLAUDE_CODE_ENVIRONMENT_KIND=bridge, thenclaude --print --sdk-url https://api.anthropic.com/v1/code/sessions/<id> --session-id <id>.
The worker attaches, resumes the interrupted turn (including re-requesting the in-flight tool permission), and the card goes connected / requires_action with history intact. 15 for 15 on the recoveries above.
Asks (unchanged)
- Server-side reconciliation:
connection_status: disconnectedfor more than N minutes should clearworker_statusso normal dispatch resumes. This alone fixes the user-facing symptom. - Expose the takeover:
claude remote-control --reconnect <session-id>doing the bridge claim above (and reconciling the local bridge-pointer lock) makes recovery a one-liner. - Document an escape hatch: even
POST <session>/archive(works, 200/409, force-closes a dead card) is absent from the Remote Control docs.
Session IDs and request IDs available on request.