fix(runtime): keep every placeholder when bounding a multi-result tool message - #4456
Merged
Astro-Han merged 1 commit intoSep 2, 2026
Conversation
…l message fitHistoryCompactMessages copied each replaced tool-result from the original message content, so a tool message batching several results (one per parallel tool call) kept only the last placeholder while the budget accounting credited all of them. The returned history could then still exceed the requested budget yet be treated as "fit". Accumulate replacements across a message's parts, matching active-tool-result-prune. Fixes apache#4454 Generated-by: Claude Code
Astro-Han
approved these changes
Sep 1, 2026
Astro-Han
left a comment
Contributor
There was a problem hiding this comment.
Confirmed the bug and the fix.
const content = [...message.content] copied from the original content every iteration, so with two oversized results the second replacement overwrote the first — while estimatedChars had already been credited twice. The early return bounded then hands back a history that claims to fit and doesn't. Parallel tool calls make that the common shape, not the corner case, which is the part that makes this worth fixing rather than noting.
The accumulating content is right, including at the early return. Reads clean to me.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fitHistoryCompactMessagesbounds a compaction request by replacing old, oversizedtool-resultpayloads with a placeholder. Each replacement copied from the originalmessage.content, so a singletoolmessage that batches several results (one per parallel tool call) kept only the last placeholder while every earlier payload stayed at full size — even though the budget accounting (estimatedChars) had already credited their removal. The helper could therefore return a history that still exceedsmaxInputEstimatedTokensyet treat it as "fit" (or, at other sizes, throwinput_too_largefor input that would actually fit), failing at exactly the case it exists to handle.The fix accumulates replacements across a message's parts, matching the pattern already used in
active-tool-result-prune.ts.Fixes #4454
Verification
npm --workspace @maka/runtime run typecheck— cleannode --test dist/__tests__/history-compact-input-fit.test.js— the newbounds every oversized result in a multi-result tool messagecase fails onmain(returns 16974 chars for a 1000-char budget, one full payload surviving) and passes with this change; the three existing cases still passnpx biome checkon both changed files — cleanAI use
Select exactly one:
Tool(s) and scope: Claude Code — diagnosis, the fix, and the test, under human review of record. A
Generated-by: Claude Codetrailer is on the commit.Checklist
Does this PR entail a change in behavior?