[Bug] API Error: Connection closed mid-response on long subagent turns causes transcript truncation

Open 💬 0 comments Opened Jul 7, 2026 by asawicki

Bug Description
The following yt-dlp executables are shadowed by other commands earlier in your PATH:
yt-dlp (shadowed by /opt/homebrew/bin/yt-dlp)
Running these by name will not invoke the version provided by Homebrew.
Disable this behaviour by setting HOMEBREW_NO_PATH_SHADOW_CHECK=1.
Hide these hints with HOMEBREW_NO_ENV_HINTS=1 (see man brew).
Environment:

  • Claude Code 2.1.201 and 2.1.202 (both stamped on affected records)
  • macOS (darwin), CLI entrypoint, direct network (no proxy/VPN)
  • Workload: a multi-agent orchestrator that fans out parallel Task subagents,

each running long, investigation-heavy plan->implement turns.

What happens:
On long subagent turns, "API Error: Connection closed mid-response. The response
above may be incomplete." fires repeatedly. On the subagent path there is NO
recovery: the subagent's JSONL transcript ends EXACTLY at the error record
(error is the last line, 0 records after), so the subagent dies mid-turn. The
main/foreground thread hits the same error but recovers and keeps going.

Evidence (from ~/.claude/projects/**/*.jsonl, ground-truthed via isApiErrorMessage==true;
a raw grep of the banner text over-counts because transcripts quote it):

  • 11 genuine events in ONE ~4.5h session (2026-07-07): 10 subagent, 1 main.
  • 9 of 10 subagent drops are the LAST record of the transcript (die mid-turn).
  • The 1 main-thread drop had 18 records after it (recovered).
  • The error record carries "error":"server_error" -> server-side close, not a

local network fault.

  • Trigger correlates with a large single-message emit (~9KB file Write) after a

long silent-reasoning span under accumulated context. A naive re-dispatch of
the same big turn drops AGAIN at the same error; only a checkpoint-resume
(smaller remaining turn) gets through -> orchestrator auto-resume is only a
partial mitigation and burns extra dispatches.

Reproduce the count on any machine:
for f in ~/.claude/projects/**/*.jsonl; do
jq -c 'select(.isApiErrorMessage==true)
| {t:.timestamp, subagent:.isSidechain, err:.error, v:.version}' "$f"
done
Then check whether the isApiErrorMessage:true record is the file's LAST line
(== wc -l) -> 0 records after == subagent died at the drop.

Expected / requested:
1) A server-side SSE heartbeat during long reasoning spans so the stream never
idles into a mid-response close; and/or
2) A client-settable retry/resume for background (Agent-tool) dispatches,
equivalent to the foreground stale-connection retry, so a dropped subagent
resumes transparently instead of dying.

Already filed on GitHub: anthropics/claude-code#75318 (this case, with JSONL
examples);

Environment Info

  • Platform: darwin
  • Terminal: iTerm.app
  • Version: 2.1.202
  • Feedback ID: 9e2f1f69-f548-493b-b3fb-a5c66857a2a5

Errors

[]

View original on GitHub ↗