fix-claude-session
v0.2.0
Published
Diagnose, repair, and extract context from corrupted Claude Code session JSONL files
Maintainers
Readme
fix-claude-session
Diagnose, repair, and recover context from corrupted Claude Code session files.
Beta (0.x) — Always creates backups before any modification. If a repair doesn't work, restore your original in seconds. Worst case: it can't fix your session, but it'll extract your context so you lose minutes, not hours.
Why this exists
Claude Code sessions accumulate context over time — decisions, reasoning, research, architectural plans, debugging insights. When a session corrupts, that context is trapped in a broken JSONL file. /rewind fails. /compact fails. Every message returns the same error:
API Error: 400 due to tool use concurrency issues.
Run /rewind to recover the conversation.This tool was built from a real debugging session where two critical sessions corrupted simultaneously — one was actively working, the other was idle. Hours of architectural context, commit history, and in-progress plans were locked behind a 400 error. We needed that context to finish the work.
This tool helps in three situations:
Corrupted sessions — Your session throws 400 errors and
/rewinddoesn't help. Repair might fix it. If not, extract pulls out your context so a new session can continue where you left off.Context transplant — You need to move context from one session to another (different project, different machine, context too large for the current model). Extract gives you a portable recovery file you can feed to any new session.
Cross-project transfer — You need to move an agent's accumulated context (decisions, research, architectural knowledge) into a different project. Transfer mode rewrites file paths and includes project metadata so the new session can pick up seamlessly.
How it works
It's fast and low-risk. The tool creates a verified backup before touching anything, and you can restore it instantly if needed. The whole diagnose → repair → extract cycle takes seconds, even on large (60MB+) sessions.
diagnose → What's wrong?
repair → Can we fix it? (backup created first)
extract → Pull out the context regardless
restore → Put it back if repair didn't helpInstall
# Run directly (no install needed)
npx fix-claude-session diagnose ~/.claude/projects/...
# Or install globally
npm install -g fix-claude-sessionRequires Node.js 18+ (if you have Claude Code, you have Node). Zero dependencies.
Usage
Diagnose — find what's broken
# Check a specific session
fix-claude-session diagnose <session.jsonl>
# Scan all sessions for issues
fix-claude-session diagnose --scan-dir ~/.claude/projects/Reports corruption types and gives you the exact commands to run next:
Status: CORRUPTED (3 issue type(s) found)
Next steps:
Repair: fix-claude-session repair /path/to/session.jsonl
Preview: fix-claude-session repair /path/to/session.jsonl --dry-run
Extract: fix-claude-session extract /path/to/session.jsonl --output recovery.mdRepair — attempt to fix
# Preview what would be fixed (no changes)
fix-claude-session repair <session.jsonl> --dry-run
# Apply repairs (creates timestamped .bak backup first)
fix-claude-session repair <session.jsonl>Repairs applied in order:
- Remove API error messages (
isApiErrorMessageentries) - Normalize string content to array format
- Inject synthetic
tool_resultfor orphanedtool_useblocks - Deduplicate tool_use IDs produced by compaction
After repair, you'll see clear next steps:
Verification: CLEAN
Try resuming: claude --resume <session-uuid>Or if issues remain:
WARNING: 1 issues remain after repair.
Next steps:
1. Try resuming: claude --resume <session-uuid>
2. If still broken: fix-claude-session extract session.jsonl --output recovery.md
3. Start fresh: claude
4. In new session: Read recovery.md for context from the old session
5. If needed: fix-claude-session restore session.jsonl 0A note on repair: Repair fixes real structural issues in the JSONL, but we haven't yet confirmed it fully resolves the 400 error in all cases. Some corruption lives deeper — in how Claude Code reconstructs conversations internally, not in the file structure itself. That said, the session was already broken, and repair can't make it worse. A backup is created and verified before any change. Try it — if it doesn't work, restore your backup in one command and fall back to extract.
Extract — recover your context
Extract pulls your conversation history out of the session file so a new session can pick up where you left off. This is your safety net when repair can't save the session.
# Full extraction — everything, no limit (default)
fix-claude-session extract <session.jsonl> --output recovery.md
# Deduplicate repeated file reads (saves 20-40% on large sessions)
fix-claude-session extract <session.jsonl> --dedup --output recovery.md
# Fit into a specific token budget (for smaller context windows)
fix-claude-session extract <session.jsonl> --tokens 100000 --output recovery.mdThen in a new Claude Code session:
Read recovery.md — this is context from a crashed session.
Check git log for recent commits. Resume where it left off.Transfer — move context between projects
Transfer builds on extract with project-aware metadata, git history, and path rewriting. Use it when you need to move an agent's accumulated context into a different project or location.
# Transfer session context to a new project
fix-claude-session extract <session.jsonl> --transfer --output transfer.md
# Transfer with path rewriting (maps old paths to new project location)
fix-claude-session extract <session.jsonl> --transfer \
--rebase-paths /workspace/old-project /Users/me/new-project \
--output transfer.mdThe transfer output includes:
- Source session metadata — session ID, working directories, git branches, timestamps
- Recent git history — last 20 commits from the session's branch (auto-detected)
- Path-rebased conversation — file references rewritten to the new project location
- Full conversation context — all the reasoning, decisions, and research
Then in the new project:
Read transfer.md — this is context from a session in another project.
The file paths have been rebased to this project. Continue the work.Transfer composes with all extract flags (--dedup, --tokens N) for budget control.
Extract modes (progressive pressure):
| Mode | Flag | What it does |
|------|------|-------------|
| Raw | (default) | Strips API errors, keeps everything else. Full recovery for 1M token models. |
| Deduped | --dedup | Also collapses repeated file reads (keeps last read per file). |
| Budgeted | --tokens N | Fits into N tokens. Auto-dedup if needed, then progressively drops tool results → tool inputs → tool calls → truncates text → drops old text. Always preserves the most recent context. |
The stats pass runs first and tells you exactly what you're working with:
Session stats:
Text: 589 blocks, ~58,649 tokens
Tool calls: 967 (~154,567 tokens)
Tool results: 967 (~288,448 tokens)
Total: ~501,664 tokens
Files read: 7 unique (6 read multiple times)
Dedup savings: ~108,684 tokens
Mode: raw (no limit)Backups & Restore — undo anything
Every repair creates a timestamped, SHA-256 verified backup. List and restore them easily:
# See what backups exist
fix-claude-session backups <session.jsonl>
# Restore interactively (shows list, you pick)
fix-claude-session restore <session.jsonl>
# Restore directly by index
fix-claude-session restore <session.jsonl> 0Restore creates its own safety backup before overwriting, so you can't accidentally lose the current state either. It's backups all the way down.
Finding your session files
# Search sessions by keyword (matches branch, worktree, content, session name)
fix-claude-session find "frontend-redesign"
fix-claude-session find "guard"
# Show most recently modified sessions
fix-claude-session find --recent
fix-claude-session find --recent 20
# Point at a different session directory (e.g., inside a Docker container)
fix-claude-session find "my-feature" --dir /home/node/.claude/projects/Each result shows the session ID, metadata, a preview of the first user message, and a ready-to-run extract command:
abc12345-def6-7890-abcd-ef1234567890
worktree: frontend-redesign · branch: feature/phase20
67.0 MB · 2h ago · /workspace/.claude/worktrees/frontend-redesign
"implement the new component architecture..."
→ fix-claude-session extract /path/to/session.jsonl --transfer --output transfer.mdYou can also find sessions manually:
# Session files live here:
ls ~/.claude/projects/
# Find by content with grep:
grep -rl "your-branch-name" ~/.claude/projects/ --include="*.jsonl"Known corruption types
| Type | Cause | Detectable | Repairable | |------|-------|-----------|------------| | Orphaned tool_use | Session killed mid-tool-execution | Yes | Yes | | Duplicate tool_use IDs | Compaction bug reuses IDs | Yes | Yes | | String content format | Voice/dictation input, some clients | Yes | Yes | | API error messages | Error entries replayed on resume | Yes | Yes | | Consecutive same-role | Symptom of above issues | Yes | Partially | | Broken parentUuid chains | Crash during write | Planned | Planned | | Thinking block interleaving | Streaming corruption | Planned | Planned | | Internal reconstruction failure | Claude Code runtime bug | No | No (use extract) |
Known limitations
- Some sessions can't be repaired at the JSONL level. The corruption may be in Claude Code's internal conversation reconstruction — how it builds the message list from the parentUuid tree, applies compaction, and merges entries. When this logic fails, no amount of file surgery can fix it. Extract is your fallback.
- No dry-run for "will this actually resume?" — The tool can verify structural correctness but can't predict whether Claude Code will accept the repaired session. You have to try resuming it.
- Concurrent corruption is real. We've observed multiple sessions corrupting simultaneously (including idle ones), suggesting some corruption originates from Claude Code itself rather than from the session files. See #39316.
Related issues
- anthropics/claude-code#39316 — Tool use concurrency 400 errors
- miteshashar/claude-code-thinking-blocks-fix — Thinking block interleaving fix
License
MIT
