#10232: Fix: Add anthropic mode for tool call ID sanitization
agents
stale
Cluster:
Tool Call ID Sanitization
## Summary
When switching from other models (e.g., Kimi K2.5) to Claude mid-session, the conversation history may contain tool call IDs with characters like `|` or `:` that Claude rejects.
## Error Message
```
400 Provider returned error {"message":"messages.3.content.1.tool_use.id: String should match pattern '^[a-zA-Z0-9_-]+$'"}
```
## Root Cause
Claude requires `tool_use.id` to match the pattern `^[a-zA-Z0-9_-]+$`. This is actually less strict than the existing `strict` mode (which only allows alphanumeric characters).
Other models like Kimi K2.5 generate tool call IDs with characters like `:` and `|` which are valid for their APIs but not for Anthropic's Claude.
## Solution
This PR adds an `anthropic` mode for tool call ID sanitization that:
1. Allows characters `[a-zA-Z0-9_-]` as required by Claude
2. Enables sanitization for all Anthropic models (not just when switching)
3. Is less strict than `strict` mode (preserves underscores and hyphens)
## Changes
- `src/agents/tool-call-id.ts`: Added `anthropic` mode to `sanitizeToolCallId` and `isValidCloudCodeAssistToolId`
- `src/agents/transcript-policy.ts`: Updated to enable sanitization for Anthropic models with the new `anthropic` mode
- Added comprehensive tests for the new mode
## Testing
Added tests to verify:
- Underscores and hyphens are preserved
- Pipes (`|`) and colons (`:`) are stripped
- Kimi K2.5 style IDs are properly sanitized
- Valid Claude-style IDs remain unchanged
- Collisions are handled with underscore suffixes
Fixes #10222
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
- Adds an `anthropic` tool-call-id sanitization mode to preserve `[_-]` while stripping characters Claude rejects (e.g. `:`/`|`).
- Updates transcript policy so Anthropic models always sanitize tool call IDs using the new mode.
- Extends transcript ID rewrite logic/tests to ensure toolCall/toolResult IDs stay paired and collision-free.
- Adds targeted unit tests for the new sanitization behavior and collision handling.
<h3>Confidence Score: 2/5</h3>
- This PR should not merge until the strict-mode collision handling bug is fixed, as it can generate invalid tool IDs in strict mode.
- The new anthropic mode itself is straightforward and well-tested, but a boolean logic bug in `makeUniqueToolId` makes strict mode produce underscore-separated IDs on collisions, violating strict’s alphanumeric-only contract and potentially breaking providers that require it.
- src/agents/tool-call-id.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#13831: fix(agents): include Anthropic in tool call ID sanitization
by lailoo · 2026-02-11
86.5%
#2806: [AI-Assisted] Fix: Repair tool_use/tool_result pairing for Claude o...
by Arthur742Ramos · 2026-01-27
84.7%
#4700: fix: deduplicate tool_use IDs and enable sanitization for Anthropic
by marcelomar21 · 2026-01-30
84.5%
#12812: fix(transcript-policy): sanitize tool call IDs for all non-OpenAI p...
by justin-nevins · 2026-02-09
84.0%
#13976: fix(anthropic): include Anthropic in tool call ID sanitization
by omair445 · 2026-02-11
83.9%
#8345: fix: prevent synthetic error repair from creating tool_result for d...
by vishaltandale00 · 2026-02-03
80.6%
#12487: fix(agents): strip orphaned tool_result when tool_use is sanitized ...
by skylarkoo7 · 2026-02-09
80.4%
#12608: fix: sanitize client tool call IDs per provider requirements
by piyushhhxyz · 2026-02-09
80.3%
#8270: fix: support snake_case 'tool_use' in transcript repair (#8264)
by heliosarchitect · 2026-02-03
79.9%
#8117: Agents: sanitize tool call ids for OpenAI
by TylonHH · 2026-02-03
79.1%