Skip to content

Bug: Session tree branching causes tool_use_id mismatch error (LLM request rejected) #4553

@SocialMDev

Description

@SocialMDev

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:

  1. Assistant message bdd232be has a tool call but terminates with error (stopReason: "error")
  2. The repair function correctly inserts a synthetic tool result as message e013cce4 with parentId: "bdd232be"
  3. A new request is made, but it has parentId: "14ec51ac" - a different branch in the session tree
  4. 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
  5. 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:

  1. 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)
  2. Check if the format detection is correct - the function looks for type === "toolUse" but maybe the format changed
  3. Add the transcript-sanitize extension to buildEmbeddedExtensionPaths() as a secondary defense

Additional Notes

  • The transcript-sanitize.js extension exists but is NOT loaded by buildEmbeddedExtensionPaths() in extensions.js - consider adding it
  • Version: clawdbot 2026.1.24-3
  • Provider: anthropic, Model: claude-opus-4-5

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions