Reconsider #26729: auto-resume after mid-response stream drop (detection already ships in v2.1.186)
Reconsider #26729 — auto-resume after a mid-response stream drop (detection already ships)
Summary
API Error: Connection closed mid-response ends the turn dead. In auto-accept / headless runs this forces a human back to the keyboard to type continue, which defeats unattended operation.
The detection half already exists in the CLI (v2.1.186) — only the re-issue half is missing:
| Layer | Status |
|---|---|
| 1. Detect the drop (byte/stream watchdog, abort cleanly) | ✅ ships (CLAUDE_ENABLE_BYTE_WATCHDOG on; CLAUDE_ENABLE_STREAM_WATCHDOG forced on in daemon/bg) |
| 2. Preserve partial state | ✅ ships (keepPartialMessageOnAbort → "The response above may be incomplete.") |
| 3. Auto-resume the interrupted turn | ❌ missing — user must manually continue |
Since detection + partial capture are already present, wiring the existing abort path into an automatic re-issue (with a "previous response was truncated; continue from the last completed step" marker so finished work isn't redone) closes the gap with little new machinery.
Observed env vars (undocumented; names/defaults may drift)
CLAUDE_ENABLE_BYTE_WATCHDOG(default on) — idle-byte abort;CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS(~1ms–30min). Emitstengu_byte_watchdog_fired.CLAUDE_ENABLE_STREAM_WATCHDOG(default off, forced on in bg/daemon) — SSE event-gap; deadlinemax(CLAUDE_STREAM_IDLE_TIMEOUT_MS, 300000). Emitstengu_streaming_stall.
Proposed bounded design
- Stream watchdog — already present; reuse it to abort the partial turn cleanly.
- Recovery snapshot — persist state up to the last complete message + the in-flight prompt; record completed tool calls (mutations like
Edit/Bashmust not be blindly re-run; read-only tools are safe to retry). - Auto-resume — re-issue the interrupted turn, injecting a truncation marker so finished work isn't redone.
Suggested config:
CLAUDE_CODE_AUTO_RESUME_ON_DROP=1— default on in headless/auto-accept, prompt in interactive.CLAUDE_CODE_MAX_RESUME_ATTEMPTS=3— bounded with backoff; give up gracefully with recovery instructions when exceeded.
Even layers 1 + 3 alone (clean detect + automatic re-issue) remove most of the babysitting burden in auto mode, without full mutation-aware recovery up front.
Local stopgap implemented in the meantime
A Stop hook (auto-resume-on-drop.mjs) that detects the drop signal in the transcript tail and re-issues the turn via decision:"block" with a "continue from the last completed step; don't re-run completed Edit/Bash mutations" marker, bounded by CLAUDE_CODE_MAX_RESUME_ATTEMPTS per session (resets on a clean turn, surfaces recovery guidance when exhausted). This proves layers 1+3 work end-to-end with no new CLI machinery.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗