Claude session rescue
Skill tsaijamey/claude-session-rescue/skills/claude-session-rescue
Rescue a stuck Claude Code session by trimming the broken tail of its JSONL transcript and resuming cleanly
npx -y skills add tsaijamey/claude-session-rescue --skill claude-session-rescueAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
This skill should be used when a Claude Code session becomes permanently stuck and cannot continue because the model returned a malformed response that the client cannot parse. It explains how to repair the session by editing its raw JSONL transcript file and then resuming. Trigger phrases: "The model's tool call could not be parsed (retry also failed)", "tool call could not be parsed", "Your tool call was malformed and could not be parsed", "session stuck and won't resume", "claude code session frozen", "rescue a broken claude code session", "fix corrupted session jsonl", "resume a dead claude session", "empty thinking block stop_reason tool_use".
The file declares its own license as AGPL-3.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
5.1 KB, 992 tokens by cl100k_base, as published. Nobody here has run it
Overview
A Claude Code session can freeze permanently when the model streams back a structurally broken assistant message: a single thinking block whose text is an empty string (signature still present), stop_reason set to tool_use, but no tool_use block anywhere in the content array. The client parser assumes stop_reason=tool_use guarantees a tool_use block, fails to find one, and errors. The automatic retry replays the same broken response, so it fails again — surfacing as "The model's tool call could not be parsed (retry also failed)." This pattern spikes with high-reasoning model variants on long sessions.
The broken records always sit at the TAIL of the session transcript: once the bug fires, the session dies and never branches further. Because the bad records have no child nodes and create no dangling tool_use/tool_result pairings, truncating the JSONL file back to the last healthy state makes the entire history self-consistent again, and --resume rebuilds a legal context.
Steps
-
Locate the transcript. Sessions live at
~/.claude/projects/<escaped-project-path>/<session-id>.jsonl. The escaped path replaces/with-. Confirm the file by matching the session id, or sort by modification time to find the most recently touched session. -
Back up before any edit. Copy the file to a
.broken-backupsibling (and optionally a second copy elsewhere). This preserves evidence and guarantees a clean restore path. Never mutate the original without a backup. -
Inspect the tail records. Parse the last 10–15 records as JSON. Print for each: line number,
type,role,uuid,parentUuid,requestId,message.id,stop_reason, and the list of content block types. This reveals turn boundaries. -
Identify turn boundaries correctly — do not over-delete. Claude Code splits ONE assistant turn across several JSONL records (a
thinkingrecord, atextrecord, atool_userecord) that all share the samerequestId/message.id. A record withstop_reason=tool_useis normal as long as a sibling record in the same turn carries the actualtool_useblock. Only flag a turn as broken when its records contain an emptythinkingandstop_reason=tool_useyet NOtool_useblock exists in the whole turn. -
Find the healthy anchor. Walking backward from the tail, skip: (a) broken assistant turns (empty thinking + stop_reason=tool_use, no tool_use block); (b) client-injected user records reading "Your tool call was malformed and could not be parsed. Please retry."; (c) the synthesized final error record (typically
requestId=None) showing "retry also failed"; (d) trailingsystemhousekeeping records. Stop at the last fully-paired record — usually atool_resultthat matches an earliertool_use, or a normal assistant record withstop_reason=end_turn. -
Truncate to the anchor. Rewrite the file containing only lines up to and including the anchor record. Preserve the original filename and a trailing newline.
-
Self-check the result. Verify three invariants: every remaining line parses as JSON; no
tool_useblock lacks a matching downstreamtool_result(no dangling tool calls); and theparentUuidchain is unbroken (the anchor becomes a clean leaf, so no parent pointers need patching). -
Resume. Run
claude --resume <session-id>. For a non-destructive smoke test first, resume with a constrained prompt (forbid continuing the prior task, forbid tool calls) and ask the model to confirm it can see prior history and restate the last action. A clean exit with an accurate history recap confirms the rescue; the resume appends fresh records ending in a normalstop_reason=end_turn.
Boundary conditions
This clean truncate-and-resume works when the bad data is at the chain tail — the overwhelming majority of these failures. If a broken record is buried mid-history with a valid subtree still hanging off it, deletion is not enough: surviving child records must have their parentUuid re-pointed to the deleted record's parent, which is materially more complex and out of scope for the simple flow. This skill repairs the session transcript; it does not patch the underlying model/streaming bug.
About
Generated by frago — An Agent OS that turns ad-hoc agent runs into reusable recipes.
Install: uv tool install frago-cli
Homepage: https://frago.ai · Docs: https://docs.frago.ai
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.