← Back to PRs

#4700: fix: deduplicate tool_use IDs and enable sanitization for Anthropic

by marcelomar21 open 2026-01-30 14:54 View on GitHub →
agents
## Summary Fixes Anthropic API rejection error: `messages.X.content.Y: tool_use ids must be unique` This issue occurs when: 1. Session transcripts accumulate multiple assistant messages with the same tool_use ID (e.g., from retries or long conversations) 2. Tool IDs contain special characters (spaces, colons) that weren't being sanitized for Anthropic ## Changes - Add deduplication logic in `repairToolUseResultPairing()` to detect and rename duplicate tool_use IDs in assistant messages (e.g., `call_1` → `call_1_2`) - Update corresponding toolResult IDs to match the remapped tool_use IDs - Enable `sanitizeToolCallIds` for Anthropic provider (previously only Google/Mistral) - Add tests for deduplication scenarios ## Test plan - [x] Existing tests pass (`session-transcript-repair.test.ts`) - [x] New tests added for duplicate ID scenarios - [x] Verified fix resolves the error in production session with duplicate IDs <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR strengthens transcript sanitization/repair for Anthropic-compatible requests by (1) enabling `sanitizeToolCallIds` for Anthropic in the transcript policy and (2) extending `repairToolUseResultPairing()` to deduplicate duplicate assistant tool_use IDs across a session and remap the corresponding toolResult IDs. Tests were updated/added to cover the new Anthropic sanitize flag and a basic duplicate-ID-across-messages scenario. The changes fit into the existing transcript hygiene pipeline (`sanitizeSessionHistory` in `src/agents/pi-embedded-runner/google.ts`), where messages are first sanitized (including tool call IDs) and then repaired to ensure strict toolCall/toolResult ordering expected by providers like Anthropic. <h3>Confidence Score: 3/5</h3> - This PR is close to safe to merge, but has a correctness edge case around duplicate IDs within a single assistant turn that could drop tool results. - The overall approach (deduplicate IDs + remap toolResult IDs, and enable sanitization for Anthropic) matches the reported provider constraint and is covered by new tests. However, the current remapping uses a Map keyed by the original ID, so duplicates within the same assistant message can collapse to one remapped ID and cause `pushToolResult` to treat later results as duplicates and drop them. That edge case could affect real transcripts if a retry duplicates blocks inside one message. - src/agents/session-transcript-repair.ts <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs