fix(session): drop duplicate tool results in sanitizeToolCalls#3162
fix(session): drop duplicate tool results in sanitizeToolCalls#3162Sayt-0 wants to merge 1 commit into
Conversation
sanitizeToolCalls already drops orphaned tool results and injects
placeholders for missing ones so toolUse/toolResult stays balanced for
strict providers like AWS Bedrock. It did not cover a second tool_result
carrying the same tool_call_id: that leaves more toolResult than toolUse
blocks and triggers the same ValidationException ("the number of
toolResult blocks ... exceeds the number of toolUse blocks of previous
turn") as the orphaned-result case behind #1676 and #1593.
Keep only the first result per tool_use and drop later duplicates.
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
The change is correct and well-scoped. sanitizeToolCalls now drops duplicate tool_result messages for the same tool_call_id before the request reaches the provider, closing the last known structural cause of AWS Bedrock's toolResult/toolUse count mismatch (ValidationException).
Production logic (session.go): The new guard is placed after the existing orphan check and before resultIDs is updated, so it fires exactly when a second result for the same tool_call_id arrives within the same pending group. flushPending resets both maps, so the guard is naturally scoped to each turn — cross-turn duplicates are already handled as orphans. No logic errors found.
Test (sanitize_orphan_test.go): TestSanitizeToolCalls_DropsDuplicateToolResult exercises the new path end-to-end. The explicit count != 1 assertion is the right guard for this case. The assertToolPairingInvariant helper is appropriately scoped to orphan detection and the test compensates for its narrower scope with the direct count check.
No issues found in the changed code.
TL;DR
sanitizeToolCallsdrops orphaned tool results and injects placeholders for missing ones, keepingtool_use/tool_resultbalanced for strict providers (AWS Bedrock, including via a LiteLLM proxy). Related to Session resume via /sessions immediately fails with Bedrock ValidationException (toolResult/toolUse mismatch) #1676 and AWS Bedrock ValidationException: Protocol violation when assistant message contains both tool_calls and content #1593.tool_resultfor the sametool_call_id.Context
AWS Bedrock rejects any turn whose toolResult blocks outnumber the previous turn's toolUse blocks:
Known structural causes and coverage:
tool_use(orphan)sanitizeToolCalls(#3001)tool_usethat never produced one (missing)tool_call_id(duplicate)Change
tool_resultwhosetool_call_idalready received a result; keep the first.sanitizeToolCalls, same spirit as fix: drop orphaned tool results on session resume #3001.Test
TestSanitizeToolCalls_DropsDuplicateToolResult(new)Notes