[BUG] claude --resume hang on multi-turn session (2.1.126, macOS arm64)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet (closest matches are #21067, #22041, #23948, #30302, but the present session does not match the bloat / persisted-output trigger described in those threads - see "Investigation methodology" below)
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
claude --resume <session-id> does not return to an interactive prompt within a reasonable wait window for a multi-turn session JSONL whose structural shape is otherwise clean (no malformed lines, no oversize entries, no embedded images, no orphaned tool_use).
The same claude binary in the same shell, same cwd, with the same hooks configured, returns to a usable prompt promptly when invoked without --resume. The failure is specific to the resume code path.
Symptom recurs across multiple distinct session JSONLs of varying size and shape, on the same machine.
What Should Happen?
--resume should return to an interactive prompt within a few seconds, regardless of session length, for a structurally clean JSONL.
Error Messages/Logs
No stderr output during the apparent freeze; the process simply does not progress to an interactive prompt. CPU usage is non-trivial during the period, suggesting active work rather than a deadlocked sleep.
Hook timing breakdown (each SessionStart hook invoked manually with representative stdin):
hook exit time
hook-a (bash) 0 19 ms
hook-b (bash) 0 22 ms
hook-c (bash) 0 153 ms
hook-d (python) 0/124 variable: <1s warm, 7-15s cold, observed 10s timeout once
hook-e (true) 0 <1 ms
hook-f (true) 0 <1 ms
No single hook accounts for the recurring hang; symptom recurs even when the variable-latency hook short-circuits (verified via its own log).
Steps to Reproduce
- From a terminal in the session's recorded cwd, run
claude --resume <session-id>against a JSONL of the shape described in "Affected session shape" below. - Observe that the process spawns and consumes CPU but does not return to an interactive prompt within multiple-minute waits across multiple attempts.
- Kill the process. Run
claude(no--resume) from the same shell. Observe normal startup. - Repeat (1) with the sanitized repro JSONL attached as a comment below. Place at
~/.claude/projects/<project-dir>/<new-uuid>.jsonl, thenclaude --resume <new-uuid>from a cwd matching the project directory's encoded path.
Affected session shape (sanitized characteristics):
- ~2.7 MB on disk
- 1271 lines, all valid JSON
- 134
tool_usecalls (Bash 93, Write 15, Read 6, Edit 5, others) - Largest single line ≈ 58 KB
- Largest single
tool_resultcontent ≈ 25 KB - Total
tool_resultcontent ≈ 252 KB - Zero
imagecontent blocks, zero base64 substrings, zero malformed lines, zero orphanedtool_usein trailing 20 entries
Claude Code Version
2.1.126 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Other (zsh in standard macOS Terminal-class emulator; symptom recurs across multiple terminal instances)
Additional Information
Investigation
I tested five hypotheses across distinct cause-classes before settling on a likely culprit. Results:
| ID | Class | Verdict | Notes |
|---|---|---|---|
| H1 | orphan-process / lock contention | Falsified | Terminating any surviving holder did not unblock subsequent attempts |
| H2 | data-shape / parse-stall | Falsified | All 1271 lines parse; no oversize entries (>500 KB); no orphans; no images |
| H3 | SessionStart hook hang | Partially falsified | Hooks contribute to perceived slowness in some runs but symptom recurs even when slow hook short-circuits |
| H4 | runtime hydration / parse / render bottleneck on resume path | Survives falsification; not yet positively confirmed | Specific to resume path; consistent with cluster of existing reports |
| H5 | environment / IDE / Node-version regression | Partially falsified | Recurs across multiple terminals; cleanroom Docker repro not yet performed |
The surviving hypothesis (H4) is consistent with all observed evidence and with the symptom pattern in the existing cluster (#21067, #22041, #23948, #30302), although the present session does not match the bloat / persisted-output trigger described in some of those threads. This may be a different signal in the same family.
Whether the runtime is genuinely deadlocking under specific conditions or running very slowly is not distinguishable from outside without a stack-frame capture; the user-visible failure mode is identical in either case.
Suggested next steps for triage
These are inputs the team can act on faster than I can from outside:
- Attempt resume against the attached sanitized repro JSONL with a profiler attached (Node
--inspector a native Instruments capture against the Mach-O process). Hot frames in JSONL parse, conversation-state hydration, or TUI buffer construction would directly confirm H4. Idle-on-event with no pending input would suggest a deadlock variant. - Bisect by session length: produce truncated copies of the repro JSONL at 25%, 50%, 75% and observe the threshold at which resume becomes usable. This isolates whether the bottleneck is per-turn linear, super-linear, or threshold-triggered.
- If the team has internal session telemetry, correlate the existing-cluster reports against resume code path instrumentation to characterize whether the slowdown is parse-time, render-time, or context-priming-time.
Mitigation in the meantime (user-side)
I have a small script that reads the JSONL outside Claude Code and primes a fresh session with a summary of the prior turns. Recovers usable continuity. Not a fix; the underlying resume-path issue remains.
Sanitized repro JSONL
Attached as a comment below. Identifiers, timestamps, and oversize tool_result text removed; structure preserved. ~2.4 MB.
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗