REPL crash on interactive `--resume` of large session JSONL (19MB / 2554 events); non-interactive `-p` resume succeeds (2.1.119, macOS arm64)
Summary
Interactive claude --resume of a 19MB / 2554-event session JSONL crashes the REPL on startup, dumping minified source context to the terminal followed by a small async stack ending at cli.js:18815. The same session loads cleanly under non-interactive claude --resume <id> -p "..." mode, so the JSONL itself is valid — the crash is in the interactive REPL render path.
This is not the wave of *KH is not a function resume crashes filed against 2.1.120 over the past 24h (#53044, #53053, #53064, #53067, #53089, #53092, #53094, #53097, #53118). I'm on 2.1.119 and the symptom is different: no thrown function-undefined error, just a source-context dump with a tiny async stack.
Environment
| | |
|---|---|
| Claude Code | 2.1.119 |
| OS | macOS 26.4.1 (Build 25E253), arm64 |
| Host Node | v25.9.0 (CLI runs in bundled Bun) |
| Shell | bash |
| Terminal | iTerm2 |
Session was written entirely by 2.1.119 (no mid-session version drift).
Repro
# Crashes — interactive resume
claude --resume e455a3ea-b7bd-4667-b735-e7aac8bf971e
# Succeeds — non-interactive resume of the same session
claude --resume e455a3ea-b7bd-4667-b735-e7aac8bf971e -p "echo hello"
# → "hello", exit 0
The session that triggers it has these properties:
- Size: 19 MB JSONL, 2554 entries, largest single line 1.23 MB
- Composition: 1106 assistant + 634 user + ~800 metadata entries (
permission-mode,agent-name,custom-title,file-history-snapshot,last-prompt,attachment,queue-operation,system) - Sidecars: 7.2 MB in
<session-id>/directory (16 subagent files, 2 tool-result sidecars) - The 1.23MB line (line 1104) is a single tool_result entry where both
messageandtoolUseResultare ~615KB each — the same payload appears stored twice on the same record.
Expected
Interactive --resume should either succeed (if the session is valid, which -p resume confirms) or fail with a clear, user-facing error message — not crash mid-render with a minified source dump.
Actual
What gets rendered to the terminal at crash (truncated for length — happy to paste full output if useful):
}`}var fL3,TkK=1000,JL3=300,ML3=5000;var Bb8=Z(()=>{P_();k_();Np();YI();OkK();__();HV();fL3=(LmH(),E8(ZmH))});var DkK={};J_(DkK,{useScheduledTasks:()=>XL3});function
XL3({isLoading:H,assistantMode:_,setMessages:q}){...}
... [several more KB of minified source from the REPL component tree, including the `pj` useCallback that
computes spinnerTip via kGK(), the Ej6 sandbox-permission callback, and the `useEffect` that writes
"Error: sandbox required but unavailable" to stderr] ...
- <anonymous> (/$bunfs/root/src/entrypoints/cli.js:9251:5663)
- WC (/$bunfs/root/src/entrypoints/cli.js:492:63749)
- pj (/$bunfs/root/src/entrypoints/cli.js:492:76948)
- fT (/$bunfs/root/src/entrypoints/cli.js:492:76827)
- pj (/$bunfs/root/src/entrypoints/cli.js:492:77745)
- fT (/$bunfs/root/src/entrypoints/cli.js:492:76827)
- pj (/$bunfs/root/src/entrypoints/cli.js:492:76926)
- fT (/$bunfs/root/src/entrypoints/cli.js:492:76827)
- pj (/$bunfs/root/src/entrypoints/cli.js:492:77745)
- fT (/$bunfs/root/src/entrypoints/cli.js:492:76827)
- async <anonymous> (/$bunfs/root/src/entrypoints/cli.js:18815:2361)
The stack alternates between pj (3 different source positions: 76948, 77745, 76926) and fT (always at 76827) — looks like a .then() async chain in the REPL component tree, not a true call-stack overflow. The visible source region around pj includes the spinner-tip useCallback (kGK({theme, readFileState, bashTools}).then(...)) and the useScheduledTasks hook (pb8).
Diagnostics — things ruled out
To save triage time:
- Not #49876 (null-byte truncation):
tr -dc '\0' < session.jsonl | wc -c→ 0 - Not #41992 (empty text block corruption):
grep -c '"text":""' session.jsonl→ 0 - Not a corrupt JSONL: every line parses as valid JSON; non-interactive
-presume works against the same file - Not #53044 et al. (2.1.120 regressions): I'm on 2.1.119
- Not a heap exhaustion of the V8/Bun process in the obvious sense: no SIGABRT message, the process renders source then exits with the stack above
- Not sandbox-related: no
sandboxconfig in~/.claude/settings.jsonor projectsettings.local.json. The sandbox-error text visible in the dumped source is just incidental code in the same region ofcli.js.
Possibly related
- #19025 — JSONL exceeds V8 heap limit on resume. Different symptom (SIGABRT) but related theme.
- #52840 — Rewind/time-travel picker hangs on ~40MB / 15k-event transcripts. Different feature, but suggests size-dependent rendering issues exist elsewhere.
- #43941 —
/resumeshows old compaction summary. Same area of code.
Notes / hypothesis (low confidence)
The fact that -p resume works but interactive resume crashes points at a render-time issue, not a session-load issue. The visible source frames during the crash include:
- The
pjuseCallback that computes spinner-tip metadata from message history — fires after each turn or replay batch - The
useScheduledTaskshook that schedules wake-ups for/loopjobs
If the resume code path replays N messages through the same per-turn callbacks that a live session uses, anything O(n) per message becomes O(n²) on a 1740-message replay. That's speculation though — the maintainers will know better.
Workaround
Non-interactive resume (-p) works. Interactively the session is unreachable; users must start fresh.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗