Resume fails with ECONNRESET when transcript is bloated by Chrome screenshots (each image stored twice in session .jsonl)
Environment
- Claude Code 2.1.220 (also reproduced on earlier 2.1.x)
- Windows 11 Pro (10.0.26200), native (not WSL)
- Claude in Chrome extension in use (
mcp__claude-in-chrome__computerscreenshots)
Symptom
API Error: Unable to connect to API (ECONNRESET) on every attempt to resume a particular session. Fully deterministic — Ctrl-C, CLI restart, and machine reboot make no difference. Network is fine (curl to api.anthropic.com succeeds immediately). Other sessions resume normally.
Root cause (measured)
The affected session's .jsonl transcript was 16.7 MB, of which 12.5 MB was 134 base64 image blocks — 67 unique Chrome screenshots, each stored twice:
- once under
message.content[].content(the tool result in the message stream), and - once again under
toolUseResulton the same line.
Single transcript lines reached 474 KB. Resume replays the whole transcript in one request, and past a few MB the upload dies with ECONNRESET — so the session becomes permanently unresumable.
Manually rewriting the transcript to replace each {"type":"image","source":{"type":"base64",...}} block with a short text stub (preserving line count and all tool/edit history) took the file from 16.7 MB → 3.46 MB and the session resumed perfectly. This confirms the images were the entire problem.
Suggested fixes (any one would resolve it)
- Don't store the image twice —
toolUseResultduplicating the full base64 payload already present inmessage.contentdoubles the cost of every screenshot for no read-path benefit I can find. - Store screenshots on disk and reference them — 2.1.207 added
save_to_diskfor Chrome screenshots; making path-reference the default storage form (with the base64 only in the live request, not the persisted transcript) would cap transcript growth. - Prune or downsample old images on resume — older screenshots are rarely needed for continuation; replacing them with stubs at resume-assembly time (as
/compacteffectively does) would keep even legacy transcripts resumable. - Failing all of the above, a clearer error than ECONNRESET ("transcript too large to resume, run /compact or strip images") would save users a long network-debugging detour.
Workaround in the meantime
A SessionStart hook that walks idle transcripts and replaces embedded base64 image blocks with text stubs (temp-file + rename, unparseable lines passed through untouched). Works, but users hitting this get a very confusing failure mode first.