Session permanently corrupted when background Task tool_use is rejected before assistant message is persisted
Bug Description
When a background Task (subagent) is stopped/rejected mid-flight, the assistant message containing the tool_use block is sometimes never written to the session JSONL log, but the corresponding tool_result rejection IS written. This creates an orphaned tool_result that permanently corrupts the session — every subsequent API call fails with:
API Error: 400 "messages.0.content.0: unexpected `tool_use_id` found in `tool_result` blocks: toolu_XXXXX.
Each `tool_result` block must have a corresponding `tool_use` block in the previous message."
The session becomes unrecoverable. /clear, /mcp, disabling MCP servers — nothing fixes it. Only starting a brand new conversation works.
Steps to Reproduce
- Start a Claude Code session with a background Task tool call (e.g., a subagent doing a broad codebase search)
- Stop/reject the background task before it completes (e.g., via the UI cancellation)
- The session immediately enters a permanent error loop
Root Cause (from JSONL log analysis)
Analyzed the corrupted session log:
- Line 171: Last valid assistant message (uuid
717031c7, a text response) - Line 172: System message
- Lines 173-174: Queue operations for the background task being killed
- Line 175:
tool_resultwithparent=d8539f11andtool_use_id=toolu_014bopr75EvmowMNwCsUvaMq(rejection of the stopped task) - UUID
d8539f11does not exist anywhere in the log — the assistant message containing thetool_usewas never persisted - No context compression events in the session — so the message was not truncated, it was simply never written
The assistant was likely still streaming when the task was stopped. The tool_result rejection was written, but the original tool_use message it references was never committed to the log.
Expected Behavior
Either:
- The assistant message containing the
tool_useshould always be persisted before anytool_resultreferencing it, OR - If the
tool_usemessage cannot be persisted, the orphanedtool_resultshould not be written either, OR - On session resume, Claude Code should detect and repair orphaned
tool_resultblocks (remove them or synthesize a matchingtool_use)
Environment
- Claude Code v2.1.47
- Model: Claude Opus 4.6
- macOS Darwin 25.3.0
- The background task was a Task tool call (subagent) for a broad search
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗