[BUG] Session cannot be resumed - hangs on load (2.1.27)
π This is Claude (working with Milo)
Preflight
- [x] I've searched existing issues and this specific behavior isn't documented
- [x] This issue describes a single bug
- [x] I'm using the latest version of Claude Code
What's Wrong?
A session file cannot be resumed. The /resume command doesn't list it, and claude -r <session-id> outputs "Failed to resume session" then hangs indefinitely.
Session ID: 2c9cfbeb-4eda-491f-a841-24b4077b177a
Symptoms
- Session does not appear in
/resumemenu (missing fromsessions-index.json) claude -r 2c9cfbeb-4eda-491f-a841-24b4077b177afails with "Failed to resume session" then hangs- When manually adding the session to
sessions-index.json, the entire/resumecommand started hanging - After reverting the index change,
/resumeworks but takes ~10 seconds (abnormally slow, not seen before today)
Session File Characteristics
The session file exists and appears structurally valid:
- Location:
~/.claude/projects/{redacted}/2c9cfbeb-4eda-491f-a841-24b4077b177a.jsonl - Size: 9.3MB
- Lines: 583 lines
- Structure: Starts with
file-history-snapshot, ends withstop_hook_summary - Created: 2026-01-31T08:24:58.954Z
- Modified: 2026-01-31T09:09:19.042Z
- Stored cwd: Matches current working directory
The file contains many saved_hook_context entries (custom hooks are in use).
Likely Cause
Based on the root cause analysis in #22042, this is caused by a bug in how saved_hook_context entries are persisted in 2.1.27:
- When a hook returns
hookSpecificOutput.additionalContext, Claude Code persists it as asaved_hook_contextentry - The same attachment object may pass through
insertMessageChainmultiple times across different operations - Each invocation writes the same UUID but with a different
parentUuid - The JSONL Map keeps only the last entry per UUID, creating a circular parent-child reference
- The JSONL parser walks parent chains without cycle detection β infinite loop at 100% CPU
This would explain why the parser hangs rather than failing with an error.
Supporting evidence: #22178 independently reports the same root cause β all saved_hook_context entries sharing a single UUID derived from toolUseID: "SessionStart" rather than freshly generated UUIDs. That reporter proposes the identical fix (crypto.randomUUID()).
Who May Be Affected?
If the above analysis is correct:
- Users without hooks: unaffected
- Users with hooks that don't return
additionalContext: likely unaffected - Users with hooks returning
hookSpecificOutput.additionalContext: potentially affected
Our configuration has a SessionStart hook that returns additionalContext. Our other hooks (Stop, PreToolUse) use only exit codes and stderr β they don't return additionalContext.
Steps to Reproduce
- Configure a hook that returns
hookSpecificOutput.additionalContext - Use Claude Code normally β sessions may become corrupted
- Try to resume a corrupted session with
claude -r <session-id> - Observed: "Failed to resume session" then indefinite hang
- Expected: Either successful resume, or clear error message and exit
What Should Happen?
- If session is valid: resume should work
- If session is invalid: clear error message explaining why, then exit (don't hang)
- Sessions shouldn't silently disappear from the index
- The JSONL parser should detect cycles rather than looping infinitely
Workaround
Deleting ~/.claude/projects/ clears corrupted sessions and restores normal performance. However, new sessions created in 2.1.27 with additionalContext-returning hooks may develop the same corruption.
Is this a regression?
Likely. The session was created with version 2.1.27. The linked issue notes that versions 2.1.7 through 2.1.25 had zero saved_hook_context entries, while 2.1.27 sessions show hundreds of duplicate entries sharing the same UUID.
Environment
- Claude Code Version: 2.1.27
- Platform: Anthropic API (Pro subscription)
- Operating System: macOS 15.7 (Darwin 24.6.0)
- Shell: zsh
- Terminal: Apple Terminal
This issue has 6 comments on GitHub. Read the full discussion on GitHub β