Background daemon sessions fail permanently on transient socket errors — no retry/reconnect
Open 💬 4 comments Opened Jun 16, 2026 by sheldon
Summary
When a background agent session encounters a transient network error (e.g. API Error: The socket connection was closed unexpectedly), the daemon marks the session as permanently failed rather than retrying with backoff. There is no automatic reconnect, and the session cannot be restarted from the CLI — only from the UI.
Steps to reproduce
- Start a long-running background agent (e.g. babysit a PR until merged, or a multi-step build task).
- Experience a brief network interruption (e.g. on a train, mobile connection drop, WiFi handoff).
- The session's
state.jsontransitions to"state": "failed"with"detail": "API Error: The socket connection was closed unexpectedly."and"tempo": "idle". - The session disappears from
claude agents --jsonoutput and cannot be resumed viaclaude --resume <id>in headless/CLI mode.
Expected behavior
- Transient socket errors should trigger exponential-backoff retry rather than immediate permanent failure.
- At minimum, the session should enter a
"state": "error"or"state": "reconnecting"state with a way to restart it from the CLI (e.g.claude agents --restart <session-id>), not only from the UI.
Actual behavior
- Session is permanently marked
failed. - All in-flight work is lost — even though
resumeSessionIdandrespawnFlagsare present instate.json, the daemon does not use them to auto-respawn. - Recovery requires opening the background agents panel in the desktop app / IDE / claude.ai and clicking Restart manually.
Impact
Any long-running background task is silently killed by a momentary network drop, with no recovery path for CLI-only users. Particularly painful for:
- Babysitting PRs/CI over hours
- Multi-step build/publish workflows
- Scheduled routines that run while the user is away from the UI
Environment
- Claude Code CLI version: 2.1.162–2.1.173 (observed across multiple versions)
- Platform: macOS darwin/zsh
- Backend: daemon
Suggested fix
- Catch socket-closed / ECONNRESET errors in the daemon's API client and retry with exponential backoff (e.g. 3 retries over 30s before giving up).
- Add
claude agents --restart <session-id>CLI command for headless recovery. - Distinguish between "transient network error" and "fatal API error" in the
statefield so tooling can act accordingly.
🤖 Generated with Claude Code
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗