#13062: fix: remove orphaned tool_result blocks from user message content during compaction (#13020)
docs
commands
agents
stale
Cluster:
Tool Result Compaction Fixes
## Summary
This PR fixes issue #13020 where tool_result blocks embedded within user message content arrays were not being removed when their corresponding tool_use blocks were dropped during conversation compaction.
## Problem
When OpenClaw compacts conversation history:
1. It may drop assistant messages containing tool_use blocks
2. But leaves corresponding tool_result blocks embedded in user message content arrays
3. This causes API errors: `unexpected tool_use_id found in tool_result blocks`
The existing repair logic only handled separate `toolResult` messages, not tool_result blocks within user message content arrays (which is how Anthropic's API actually formats them).
## Solution
Enhanced `repairToolUseResultPairing` to handle both formats:
- Separate messages with role "toolResult" (existing behavior)
- tool_result blocks within user message content arrays (new behavior)
### Implementation Details
1. **First pass**: Collect all valid tool_use IDs from assistant messages
2. **Process user messages**: Remove orphaned tool_result blocks from content arrays
3. **Track orphans**: Count removed blocks in `droppedOrphanCount` for diagnostics
## Testing
Added comprehensive test coverage in `compaction-13020.test.ts`:
- ✅ Removes orphaned tool_result blocks from user message content
- ✅ Keeps tool_result blocks when their tool_use is also kept
- ✅ Handles mixed content (text + tool_results) correctly
- ✅ All existing compaction tests still pass
## Changes
- `src/agents/session-transcript-repair.ts`: Added logic to handle tool_result blocks in user content
- `src/agents/compaction-13020.test.ts`: New test file with comprehensive coverage
Fixes #13020
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR primarily fixes transcript compaction by extending `repairToolUseResultPairing` to remove orphaned `tool_result` blocks embedded inside `user` message content arrays (not just standalone `toolResult` messages). It adds targeted tests reproducing the API error scenario when a chunk containing the assistant `toolUse` is dropped but the user’s `tool_result` block remains.
In addition, the PR introduces a new `doctor-memory` diagnostic that warns when memory search embeddings are enabled but no provider/API keys/local model are configured, and it adds a new cache infrastructure module (manager, LRU provider, and integrations for model-response and web-search caching).
<h3>Confidence Score: 3/5</h3>
- This PR is mergeable after addressing a couple of correctness issues in newly added diagnostics/caching code.
- The core compaction/transcript repair change is straightforward and covered by new tests, but the PR also introduces new doctor-memory and cache modules where there are at least two concrete logic issues: a `.trim()` call that can throw on malformed config types in a diagnostic path, and a key-shape mismatch in model-response similarity lookups that makes the similarity path ineffective (or not aligned with the stored entries).
- src/commands/doctor-memory.ts, src/infra/cache/integrations/model-response-cache.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#16095: fix: remove orphaned tool_result blocks during compaction (#15691)
by claw-sylphx · 2026-02-14
86.7%
#11825: fix: keep tool_use/tool_result pairs together during session compac...
by C31gordon · 2026-02-08
86.0%
#4852: fix(agents): sanitize tool pairing after compaction and history tru...
by lailoo · 2026-01-30
85.9%
#12487: fix(agents): strip orphaned tool_result when tool_use is sanitized ...
by skylarkoo7 · 2026-02-09
85.7%
#9416: fix: drop errored/aborted assistant tool pairs in transcript repair
by xandorklein · 2026-02-05
85.4%
#4844: fix(agents): skip error/aborted assistant messages in transcript re...
by lailoo · 2026-01-30
84.8%
#8345: fix: prevent synthetic error repair from creating tool_result for d...
by vishaltandale00 · 2026-02-03
84.5%
#6687: fix(session-repair): strip malformed tool_use blocks to prevent per...
by NSEvent · 2026-02-01
84.3%
#14328: fix: strip incomplete tool_use blocks from errored/aborted messages...
by Kropiunig · 2026-02-12
84.2%
#15050: fix: transcript corruption resilience — strip aborted tool_use bloc...
by yashchitneni · 2026-02-12
84.0%