Skip to content

fix(messageConversion): deduplicate tool results for reused tool_call_ids (#12626)#12627

Open
aryan105825 wants to merge 1 commit into
continuedev:mainfrom
aryan105825:main
Open

fix(messageConversion): deduplicate tool results for reused tool_call_ids (#12626)#12627
aryan105825 wants to merge 1 commit into
continuedev:mainfrom
aryan105825:main

Conversation

@aryan105825

@aryan105825 aryan105825 commented Jun 14, 2026

Copy link
Copy Markdown

I have read the CLA Document and I hereby sign the CLA

Description

When a provider reuses a tool_call_id across turns, Continue was emitting
duplicate tool_result entries for that ID on every subsequent request to the
provider. This corrupts provider conversation state, triggers schema validation
errors, and can cause runaway retry loops (the reproducer in #12626 shows 441
duplicate entries across 442 requests for a single reused ID).

Root cause: handleToolResult in messageConversion.ts matched tool results
against a global pendingToolCalls map without scoping to the current assistant
turn. When the same ID was reused in a later turn, the earlier turn's
toolCallStates entry still existed and got re-emitted on every serialization
pass by convertFromUnifiedHistory.

Two fixes in core/util/messageConversion.ts:

  1. handleToolResult: guard the match so it only applies when the
    tool_call_id belongs to the current assistant turn's toolCallStates.
    After a successful match, delete the ID from pendingToolCalls so a reused
    ID in a later turn is treated as a fresh entry.

  2. convertFromUnifiedHistory: track emitted tool_call_ids in a Set
    and skip duplicates on emit — a defensive second layer in case any other
    code path populates toolCallStates with a reused ID.

Checklist

  • I've read the contributing guide
  • The relevant docs, if any, have been updated or created
  • The relevant tests, if any, have been updated or created

Screen recording or screenshot

N/A — this is a bug fix with no visual output. The reproducer in #12626 can be
used to verify: expected output changes from REPRODUCED to no duplicate
entries logged.

Tests

Added unit tests in core/util/messageConversion.test.ts covering:

  • Tool results are emitted exactly once when tool_call_id is unique across turns
  • Tool results are not duplicated when a tool_call_id is reused across turns
  • convertToUnifiedHistoryconvertFromUnifiedHistory round-trip produces
    a valid, non-duplicated message sequence for reused IDs

Summary by cubic

Deduplicates tool results when a provider reuses a tool_call_id across turns, preventing corrupted conversation state and retry loops. Fixes #12626.

  • Bug Fixes
    • handleToolResult: only match IDs in the current assistant turn and remove the ID from pendingToolCalls after emit.
    • convertFromUnifiedHistory: track emitted tool_call_ids in a Set and skip duplicates as a defensive layer.

Written for commit 675749d. Summary will update on new commits.

Review in cubic

…n history

Fixes continuedev#12626

When a provider reuses a tool_call_id across turns, Continue was emitting
duplicate tool_result entries for that ID on every subsequent request,
corrupting provider conversation state.

Two fixes in core/util/messageConversion.ts:

1. handleToolResult: scope ID lookup to the current assistant turn only,
   and consume matched IDs from pendingToolCalls so a reused ID in a
   later turn starts fresh.

2. convertFromUnifiedHistory: track emitted tool_call_ids in a Set and
   skip duplicates, as a defensive second layer against any other path
   that could populate toolCallStates with a reused ID.
@aryan105825 aryan105825 requested a review from a team as a code owner June 14, 2026 18:24
@aryan105825 aryan105825 requested review from sestinj and removed request for a team June 14, 2026 18:24
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jun 14, 2026
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@aryan105825

Copy link
Copy Markdown
Author

recheck

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

@aryan105825

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

Continue sends duplicate tool-result history for a reused tool-call id

1 participant