Skip to content

Conversation

@daniel-lxs
Copy link
Member

@daniel-lxs daniel-lxs commented Jan 12, 2026

Summary

Fixes orphaned tool_use blocks error during conversation condensation.

Error: ApiProviderError: messages.50: 'tool_use' ids were found without 'tool_result' blocks immediately after: toolu_011CmkW5Ho9AqFuiC84xuYBb

PostHog issue: https://us.posthog.com/error_tracking/019ba58c-53b6-7592-8988-d7518c59512c

Root Cause

The Anthropic API requires every tool_use block in an assistant message to have a corresponding tool_result block in the immediately following user message. During conversation condensation, the bounded search (only last 3 messages) failed to find tool_use blocks that were further back in history, causing orphaned tool_result blocks.

Solution

Replaced the bounded linear search with a performance-optimized indexed lookup:

  1. Collect all tool_use IDs we need to find from kept messages
  2. Early exit if no tool_results in kept messages
  3. Build index in ONE pass through the condensed region (Map of tool_use ID → message)
  4. O(1) lookups instead of repeated O(n) searches

Performance Analysis

Scenario Before (Bounded) After (Indexed)
No tool_results in kept messages O(1) O(1) early exit
1 tool_result, 500 msgs O(3) O(n) one pass + O(1) lookup
5 tool_results, 500 msgs O(15) O(n) one pass + O(5) lookups

Memory footprint is minimal - only stores references to messages we're looking for.

Testing

All 44 condensation tests pass.

Fixes ROO-516


Important

Replaces linear search with indexed lookup in getKeepMessagesWithToolBlocks() to preserve tool_use blocks, preventing orphaned tool_result blocks and improving performance.

  • Behavior:
    • Replaces bounded linear search with indexed lookup in getKeepMessagesWithToolBlocks() in index.ts to preserve tool_use blocks regardless of position.
    • Ensures tool_use blocks are preserved even if far back in history, preventing orphaned tool_result blocks.
  • Performance:
    • Indexed lookup provides O(1) lookups for tool_use blocks, improving from O(n) linear searches.
    • Early exit if no tool_results in kept messages.
  • Testing:
    • Updates tests in index.spec.ts to verify preservation of tool_use blocks and reasoning blocks.
    • All 44 condensation tests pass.

This description was created by Ellipsis for e00e0c7. You can customize this summary. It will automatically update as commits are pushed.

The Anthropic API requires every tool_use block to have a corresponding
tool_result in the next user message. During conversation condensation,
the bounded search (only last 3 messages) failed to find tool_use blocks
that were further back in history, causing orphaned tool_result blocks.

This fix replaces the bounded linear search with a performance-optimized
indexed lookup:

1. Collect all tool_use IDs we need to find from kept messages
2. Early exit if no tool_results in kept messages
3. Build index in ONE pass through the condensed region
4. O(1) lookups instead of repeated O(n) searches

Fixes: ROO-516
@daniel-lxs daniel-lxs requested review from cte, jr and mrubens as code owners January 12, 2026 23:41
@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels Jan 12, 2026
@roomote
Copy link
Contributor

roomote bot commented Jan 12, 2026

Rooviewer Clock   See task on Roo Cloud

Review complete. The fix correctly addresses the orphaned tool_use blocks error by replacing the bounded search with an indexed lookup that searches the entire condensed region. One minor cleanup item found:

  • Remove unused findLast import from src/core/condense/index.ts

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

const preservedToolUseIds = new Set<string>()

// Check ALL kept messages for tool_result blocks
// First, collect all tool_use_ids we need to find from kept messages
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor cleanup: The findLast import from ../../shared/array at line 10 is now unused since this refactoring replaced the linear search with a Map-based lookup. Consider removing it.

Fix it with Roo Code or mention @roomote and request a fix.

@daniel-lxs daniel-lxs marked this pull request as draft January 12, 2026 23:48
@daniel-lxs
Copy link
Member Author

Closing this PR. The Anthropic API requires tool_result to immediately follow tool_use, making them always adjacent. The old bounded search (3 messages back from startIndex) already covered startIndex-1 where an adjacent tool_use would be. The extended search only helps if tool_use and tool_result are non-adjacent, which is an invalid conversation state that cannot occur through normal API interactions. The test case is contrived - it places tool_use at ts:1 and tool_result at ts:9 which the API would reject. If this error is occurring in production, the root cause is something creating invalid message ordering, not a condensation search boundary issue.

@daniel-lxs daniel-lxs closed this Jan 12, 2026
@github-project-automation github-project-automation bot moved this from New to Done in Roo Code Roadmap Jan 12, 2026
@github-project-automation github-project-automation bot moved this from Triage to Done in Roo Code Roadmap Jan 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:M This PR changes 30-99 lines, ignoring generated files.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants