fix: re-run sanitization after limitHistoryTurns to fix orphaned tool results#5032
fix: re-run sanitization after limitHistoryTurns to fix orphaned tool results#5032shayan919293 wants to merge 1 commit intoopenclaw:mainfrom
Conversation
… results After limitHistoryTurns cuts off older messages, tool_use blocks can be removed while their corresponding tool_result blocks remain, creating orphaned tool results that cause Anthropic API to reject requests. Similarly, the limiting can create consecutive assistant messages that violate Gemini's format requirements. This fix re-runs sanitizeToolUseResultPairing, validateGeminiTurns, and validateAnthropicTurns after the history limit is applied, repairing any issues created by the cut-off. Closes openclaw#4650
| const postLimitRepaired = transcriptPolicy.repairToolUseResultPairing | ||
| ? sanitizeToolUseResultPairing(limited) | ||
| : limited; | ||
| const postLimitGemini = transcriptPolicy.validateGeminiTurns |
There was a problem hiding this comment.
[P2] Post-limit pass may insert synthetic tool results, not just dropsessionphans.
The comment says this is to "fix any orphaned tool results", but sanitizeToolUseResultPairing() delegates to repairToolUseResultPairing(), which also inserts synthetic error tool results for missing tool calls (makeMissingToolResult() in src/agents/session-transcript-repair.ts:38-55). After limitHistoryTurns() truncation, that can happen if the tool call remains but the matching tool result was truncated, increasing message count and potentially affecting token budgeting/compaction behavior. If the intent here is strictly to drop orphaned tool_results (as described in the PR), consider either adjusting the comment to reflect the insertion behavior, or using the repair report to drop-orphans-only in this post-limit step.
Also appears in src/agents/pi-embedded-runner/compact.ts:427-432.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/pi-embedded-runner/run/attempt.ts
Line: 542:545
Comment:
[P2] Post-limit pass may *insert* synthetic tool results, not just dropsessionphans.
The comment says this is to "fix any orphaned tool results", but `sanitizeToolUseResultPairing()` delegates to `repairToolUseResultPairing()`, which also **inserts synthetic error tool results** for missing tool calls (`makeMissingToolResult()` in `src/agents/session-transcript-repair.ts:38-55`). After `limitHistoryTurns()` truncation, that can happen if the tool call remains but the matching tool result was truncated, increasing message count and potentially affecting token budgeting/compaction behavior. If the intent here is strictly to *drop orphaned tool_results* (as described in the PR), consider either adjusting the comment to reflect the insertion behavior, or using the repair report to drop-orphans-only in this post-limit step.
Also appears in `src/agents/pi-embedded-runner/compact.ts:427-432`.
How can I resolve this? If you propose a fix, please make it concise.|
Closing as duplicate of #13974. If this is incorrect, comment and we can reopen. |
Summary
After
limitHistoryTurnscuts off older messages,tool_useblocks can be removed while their correspondingtool_resultblocks remain, creating orphaned tool results that cause the Anthropic API to reject requests with errors like:Similarly, the limiting can create consecutive assistant messages that violate Gemini's format requirements.
Fix
This fix re-runs the sanitization functions after
limitHistoryTurnsis applied:sanitizeToolUseResultPairing()- drops orphaned tool results created by the cut-offvalidateGeminiTurns()- merges consecutive assistant messagesvalidateAnthropicTurns()- merges consecutive user messagesThe same fix is applied to both:
src/agents/pi-embedded-runner/run/attempt.ts(main request path)src/agents/pi-embedded-runner/compact.ts(compaction path)Testing
Closes #4650
Pull Request opened by Augment Code with guidance from the PR author
Greptile Overview
Greptile Summary
This PR updates the embedded Pi runner and compaction code paths to re-run transcript sanitization after
limitHistoryTurns()is applied. The intent is to fix cases where truncation can leave orphanedtool_resultmessages (without their precedingtool_use) and can create consecutive same-role turns that certain providers reject (e.g., Gemini assistant-assistant or Anthropic user-user turns). The change adds a post-limit pass ofsanitizeToolUseResultPairing(),validateGeminiTurns(), andvalidateAnthropicTurns()before persisting the truncated message list back into the session.Confidence Score: 4/5
sanitizeToolUseResultPairing()can insert synthetic tool results for missing tool calls, and re-running it after truncation could add new synthetic entries; whether that is always desired depends onTranscriptPolicyexpectations. CI/test execution couldn't be verified in this environment (no node/pnpm available).