-
-
Notifications
You must be signed in to change notification settings - Fork 40.4k
Description
Summary
Even with the transcript-sanitize extension loaded (fix from #6118), long sessions still hit "unexpected tool_use_id found in tool_result blocks" errors from the Anthropic API. The root cause is in the upstream @mariozechner/pi-ai package's transformMessages() function, which runs after Clawdbot's transcript repair.
Error
Profile anthropic:claude-cli hit Cloud Code Assist format error. Tool calls will be sanitized on retry.
FailoverError: LLM request rejected: messages.268.content.1: unexpected tool_use_id found in tool_result blocks: toolu_01YDDkR7xihJHDSiQdF8VyzV
Environment
- Clawdbot v2026.1.24-3 (with Bug: transcript-sanitize extension never loaded — causes tool_use_id mismatch in long sessions #6118 patch applied)
@mariozechner/pi-aiv0.49.3- Anthropic provider (Claude Opus 4.5, claude-cli profile)
- Long-running session (268+ messages)
Relationship to #6118 and #4650
| Issue | What it fixes | Status |
|---|---|---|
| #6118 | transcript-sanitize extension not loaded |
✅ Patch applied — extension now runs |
| #4650 | limitHistoryTurns creating orphans after repair |
✅ Mitigated by #6118 — extension re-repairs on every context build |
| This issue | transformMessages (pi-ai) creates NEW orphans after extension runs |
❌ Unfixed — different layer |
Root Cause
transformMessages() in @mariozechner/pi-ai (src/providers/transform-messages.ts) strips assistant messages with stopReason === "error" || "aborted" but keeps their toolResult messages. This happens inside the Anthropic provider's convertMessages(), which runs after the transformContext hook where Clawdbot's extension operates:
transformContext hook → repairToolUseResultPairing ✅ (all paired correctly)
↓
convertMessages → transformMessages → strips error'd assistant, keeps results ❌
↓
convertMessages → builds user message with orphaned tool_result blocks
↓
Anthropic API → rejects
Clawdbot cannot fix this from its side because the orphans are created inside the pi-ai provider after all hooks have run.
Additional note: misleading retry log
The log message "Tool calls will be sanitized on retry" is misleading — the retry path rotates auth profiles but does not add any additional sanitization. The same corrupt transcript is sent again, hitting the same error.
Workaround
Patch node_modules/@mariozechner/pi-ai/dist/providers/transform-messages.js directly (overwritten on update):
+ const skippedToolCallIds = new Set();
for (let i = 0; i < transformed.length; i++) {
const msg = transformed[i];
if (msg.role === "assistant") {
const assistantMsg = msg;
if (assistantMsg.stopReason === "error" || assistantMsg.stopReason === "aborted") {
+ for (const block of assistantMsg.content) {
+ if (block.type === "toolCall" && block.id) {
+ skippedToolCallIds.add(block.id);
+ }
+ }
continue;
}
}
else if (msg.role === "toolResult") {
+ if (skippedToolCallIds.has(msg.toolCallId)) {
+ continue;
+ }
existingToolResultIds.add(msg.toolCallId);
result.push(msg);
}