#20538: fix: handle orphaned tool_result errors gracefully instead of leaking to chat
agents
size: XS
Cluster:
Error Handling in Agent Tools
## Problem
Fixes #11038
When a session transcript becomes corrupted (e.g. after compaction or a crash leaves a `tool_result` block without its matching `tool_use`), Anthropic's API rejects every subsequent request with:
> unexpected tool_use_id found in tool_result blocks: toolu_01HjX9c7NLJaBLDzyBasSkKw. Each tool_result block must have a corresponding tool_use block in the previous message.
This raw API error is surfaced verbatim to the chat surface on every message, effectively spamming the channel.
## Solution
Add `isOrphanedToolResultError()` in `formatAssistantErrorText()` to detect this error pattern and rewrite it to a user-friendly message:
> Session history is corrupted (orphaned tool result without matching tool call). Use /new to start a fresh session.
This stops the error spam and gives users a clear action to resolve the issue.
## Related
- #7867 (malformed tool call errors)
- #16673 (centralized outbound sanitization)
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Added detection and user-friendly handling for orphaned `tool_result` errors that occur when session transcripts become corrupted (e.g., after compaction or crashes leave a `tool_result` block without its matching `tool_use`). Previously, Anthropic's raw API error would spam the chat on every subsequent message. The fix introduces `isOrphanedToolResultError()` to detect the error pattern and rewrites it to: "Session history is corrupted (orphaned tool result without matching tool call). Use /new to start a fresh session."
- Follows existing error-handling patterns in `src/agents/pi-embedded-helpers/errors.ts:479-484`
- Regex pattern comprehensively matches Anthropic's error variations
- Clear, actionable user-facing message that explains the issue and provides recovery steps
<h3>Confidence Score: 5/5</h3>
- Safe to merge - focused bug fix with clear benefits and no identified risks
- The change is minimal, well-targeted, and follows established patterns in the codebase. It addresses a real user-facing issue (error spam) with a clear recovery path. The regex pattern is comprehensive and the error handling is positioned correctly in the cascade. While test coverage for the new function would be ideal, the change is low-risk and the existing test infrastructure validates that `formatAssistantErrorText` processes errors correctly.
- No files require special attention
<sub>Last reviewed commit: aa01ece</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#21195: fix: suppress orphaned tool_use/tool_result errors after session co...
by ruslansychov-git · 2026-02-19
87.9%
#12487: fix(agents): strip orphaned tool_result when tool_use is sanitized ...
by skylarkoo7 · 2026-02-09
85.1%
#14328: fix: strip incomplete tool_use blocks from errored/aborted messages...
by Kropiunig · 2026-02-12
85.0%
#3362: fix: auto-repair and retry on orphan tool_result errors
by samhotchkiss · 2026-01-28
84.6%
#4844: fix(agents): skip error/aborted assistant messages in transcript re...
by lailoo · 2026-01-30
84.6%
#11825: fix: keep tool_use/tool_result pairs together during session compac...
by C31gordon · 2026-02-08
84.0%
#15050: fix: transcript corruption resilience — strip aborted tool_use bloc...
by yashchitneni · 2026-02-12
83.6%
#4009: fix(agent): sanitize messages after orphan user repair
by drag88 · 2026-01-29
83.3%
#9416: fix: drop errored/aborted assistant tool pairs in transcript repair
by xandorklein · 2026-02-05
82.9%
#13062: fix: remove orphaned tool_result blocks from user message content d...
by trevorgordon981 · 2026-02-10
82.4%