Skip to content

fix: prevent orphaned tool results during interrupted tool execution#2

Open
michaeljabbour wants to merge 1 commit intomicrosoft:mainfrom
michaeljabbour:fix/tool-result-compaction-bug
Open

fix: prevent orphaned tool results during interrupted tool execution#2
michaeljabbour wants to merge 1 commit intomicrosoft:mainfrom
michaeljabbour:fix/tool-result-compaction-bug

Conversation

@michaeljabbour
Copy link

Summary

Fixes a critical bug in context compaction that caused orphaned tool results and API errors when users interrupted tool execution.

Bug Description

The _check_tool_pair_removable() method was incorrectly marking tool pairs as removable even when not all tool_results had been received yet. This caused the assistant message with tool_calls to be removed prematurely, leaving orphaned tool_result messages that triggered Anthropic API errors.

Root Cause

  • Method only checked if tool_results existed in the block range
  • Did not verify that EVERY tool_call had a corresponding tool_result
  • Returned all_removable=True after finding just one result

Trigger Scenario

  1. Assistant makes tool_calls [A, B, C]
  2. Result A arrives
  3. User interrupts with 'continue' message
  4. Compaction runs, finds only result A
  5. BUG: Returns all_removable=True anyway
  6. Removes assistant message containing all tool_calls
  7. Results B and C arrive later as orphans
  8. API error: tool_use ids were found without tool_result blocks

The Fix

  • Added 'found' flag to track each individual tool_call
  • Only set all_removable=True if ALL tool_calls have results
  • Added detailed docstring explaining the critical validation
  • Added 2 regression tests to prevent reintroduction of this bug

Files Changed

  • amplifier_module_context_simple/__init__.py: Fixed _check_tool_pair_removable() method (18 lines)
  • tests/test_tool_pair_compaction.py: Added 2 regression tests (108 lines)

Impact

  • User-facing: Fixes session crashes when users interrupt tool execution
  • Safety: Prevents data loss from dropped tool results
  • Backward compatible: No API changes, just more robust logic

Testing

Added two comprehensive regression tests:

  1. test_incomplete_tool_results_not_removed() - Verifies bug is fixed
  2. test_complete_tool_results_can_be_removed() - Verifies normal case still works

Type

fix

The _check_tool_pair_removable() method was incorrectly marking tool pairs
as removable even when not all tool_results had been received yet. This
caused the assistant message with tool_calls to be removed prematurely,
leaving orphaned tool_result messages that triggered API errors.

Root cause:
- Method only checked if tool_results existed in the block range
- Did not verify that EVERY tool_call had a corresponding tool_result
- Returned all_removable=True after finding just one result

Bug trigger scenario:
1. Assistant makes tool_calls [A, B, C]
2. Result A arrives
3. User interrupts with 'continue' message
4. Compaction runs, finds only result A
5. BUG: Returns all_removable=True anyway
6. Removes assistant message containing all tool_calls
7. Results B and C arrive later as orphans
8. API error: 'tool_use ids were found without tool_result blocks'

The fix:
- Added 'found' flag to track each individual tool_call
- Only set all_removable=True if ALL tool_calls have results
- Added detailed docstring explaining the critical validation
- Added regression tests to prevent reintroduction of this bug

Impact:
- Fixes session crashes when users interrupt tool execution
- Prevents data loss from dropped tool results
- No API changes, backward compatible
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant