← Back to PRs

#22011: fix(transcript): drop empty toolCallId toolResults during persistence + repair

by sauerdaniel open 2026-02-20 16:42 View on GitHub →
agents size: S
## Summary Prevent malformed `toolResult` entries with empty/missing `toolCallId` from being persisted or retained during transcript repair. ## Problem Issue #21985 reports sessions becoming poisoned by phantom/orphan `toolResult` entries with blank IDs. Once these land in transcript history, strict providers can reject subsequent requests because `toolResult` pairing no longer matches any valid `tool_use` id. ## Solution 1. **Guard at write time** (`session-tool-result-guard.ts`) - Drop `toolResult` messages when `extractToolResultId(...)` returns empty/missing ID. - This prevents malformed tool results from ever entering persisted session history. 2. **Repair at sanitize time** (`session-transcript-repair.ts`) - Drop `toolResult` entries with empty/missing IDs during `repairToolUseResultPairing`. - This cleans existing corrupted transcripts defensively. 3. **Regression tests** - Added test: drops empty `toolCallId` in guard flow. - Added test: drops empty `toolCallId` in transcript repair flow. ## Testing - `pnpm check` ✅ - `pnpm build` ✅ - `pnpm exec vitest run --config vitest.e2e.config.ts src/agents/session-transcript-repair.e2e.test.ts src/agents/session-tool-result-guard.e2e.test.ts src/agents/session-tool-result-guard.tool-result-persist-hook.e2e.test.ts` ✅ (30/30) ## Local Validation - `pnpm build` ✅ - `pnpm check` ✅ - `pnpm test` ➖ (targeted e2e suites above; full matrix deferred to CI) ## AI-Assisted This PR was developed with AI assistance. Fixes #21985 <!-- greptile_comment --> <h3>Greptile Summary</h3> Prevents malformed `toolResult` entries with empty/missing `toolCallId` from being persisted to session transcripts or retained during repair, addressing session poisoning issues with strict providers (Anthropic, MiniMax, Cloud Code Assist). - Added guard at write time in `session-tool-result-guard.ts` to drop toolResults when `extractToolResultId()` returns empty/null - Added repair logic in `session-transcript-repair.ts` to drop empty-ID toolResults during `repairToolUseResultPairing()` - Both changes include detailed comments referencing issue #21985 - Regression tests added for both guard and repair flows <h3>Confidence Score: 5/5</h3> - Safe to merge with no issues found - The changes are minimal, focused, and well-tested. The implementation correctly handles the edge case of empty toolCallIds at both persistence and repair time. The code follows existing patterns, includes clear comments, and has comprehensive test coverage. No logical errors, security issues, or side effects identified. - No files require special attention <sub>Last reviewed commit: 764c1fa</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs