-
-
Notifications
You must be signed in to change notification settings - Fork 55.9k
Description
Bug: Session tree branching causes tool_use_id mismatch error
Error Message
LLM request rejected: messages.136.content.1: unexpected tool_use_id found in tool_result blocks: toolu_01Q1BaXmp2s7A2Xqu18Zd9mR. Each tool_result block must have a corresponding tool_use block in the previous message.
Root Cause Analysis
The sanitizeToolUseResultPairing() function in session-transcript-repair.js correctly identifies missing tool results and inserts synthetic error results. However, this fix fails when the session tree branches.
Sequence of events:
- Assistant message
bdd232behas a tool call but terminates with error (stopReason: "error") - The repair function correctly inserts a synthetic tool result as message
e013cce4withparentId: "bdd232be" - A new request is made, but it has
parentId: "14ec51ac"- a different branch in the session tree - When building the conversation history from the tree, the assistant message with the orphaned tool call is included, but the synthetic tool result on the other branch is NOT included
- The API rejects the request because the tool_result references a tool_use that doesn't exist in the conversation path
Location of Fix
The fix at attempt.js:452 calls sanitizeToolUseResultPairing() on the limited messages AFTER history truncation. However, this happens AFTER the session tree is resolved to a linear history.
The issue is that the session tree can have branches where:
- Branch A: assistant(tool_call) → synthetic_tool_result → ...
- Branch B: assistant(tool_call) → user_message → ... (missing tool_result)
When Branch B is selected as the conversation path, the orphaned tool call is included without its result.
Suggested Fix
The sanitizeToolUseResultPairing() function is already called at the right place (line 452 of attempt.js). The bug is that it checks for role === "toolResult" as a separate message, but when the session tree is linearized, the tool result might be on a different branch.
Potential solutions:
- Ensure
sanitizeToolUseResultPairing()synthesizes missing tool results for ALL assistant tool calls that don't have matching results in the linearized history (currently it does this, but something may be bypassing it) - Check if the format detection is correct - the function looks for
type === "toolUse"but maybe the format changed - Add the
transcript-sanitizeextension tobuildEmbeddedExtensionPaths()as a secondary defense
Additional Notes
- The
transcript-sanitize.jsextension exists but is NOT loaded bybuildEmbeddedExtensionPaths()inextensions.js- consider adding it - Version: clawdbot 2026.1.24-3
- Provider: anthropic, Model: claude-opus-4-5