Skip to content

fix(kosong): recognize OpenAI-compatible tool_call_id 400 as a recoverable tool-exchange error - #1292

Merged
RealKai42 merged 1 commit into
mainfrom
kaiyi/ottawa
Jul 2, 2026
Merged

fix(kosong): recognize OpenAI-compatible tool_call_id 400 as a recoverable tool-exchange error#1292
RealKai42 merged 1 commit into
mainfrom
kaiyi/ottawa

Conversation

@RealKai42

Copy link
Copy Markdown
Collaborator

Problem

A field session (exported debug zip) was permanently stuck: every turn failed with

Error: [provider.api_error] 400 tool_call_id  is not found

The history contained a tool message whose tool_call_id had no matching tool_calls entry in the immediately preceding assistant message (a user message had been interleaved into the tool exchange). Moonshot validates this before generation and rejects the request deterministically — and since the same history is re-sent every turn, the session could never recover.

Root cause

The recovery chain for exactly this situation already exists (#1241): repairToolExchangeAdjacency in the normal projection, plus a one-shot strict resend (strictMessages: adjacency repair + orphan-result drop + synthetic results) in executeLoopStep when the provider rejects the request structure.

But the trigger, isRecoverableRequestStructureError, only matched Anthropic's phrasing (tool_use/tool_result, roles must alternate, ...). The OpenAI-compatible phrasing used by Moonshot / Kimi — tool_call_id ... is not found — matched nothing, so the strict resend never fired for the default provider and the session stayed bricked. (In the field log: turn failed with no resending with strict projection line before it.)

Fix

Add a tool_call_id-anchored pattern to TOOL_EXCHANGE_ADJACENCY_MESSAGE_PATTERNS:

/tool_call_id[\s\S]*not found/

Anchored on tool_call_id so an unrelated "not found" body (e.g. 404-style) cannot trip the recovery; still gated on status 400/422 and not-context-overflow, and the resend remains one-shot.

Tests

  • kosong/test/errors.test.ts: classifier accepts the field-observed message (doubled space verbatim) for 400 and 422, on both isToolExchangeAdjacencyError and isRecoverableRequestStructureError; negative case: 400 resource not found does not match.
  • agent-core/test/loop/tool-exchange-fallback.e2e.test.ts: end-to-end — Moonshot-phrased 400 triggers exactly one strict resend and the turn recovers.
  • Written red-first: all three new assertions failed before the one-line pattern change.
  • Full suite: kosong 1133 passed; repo-wide green except 6 pre-existing failures in apps/kimi-code/test/cli/update/preflight.test.ts (verified pre-existing via stash on a clean tree).

…rable tool-exchange error

Moonshot / Kimi (OpenAI-compatible) rejects a history whose tool message
references a tool_call_id with no matching tool_calls entry in the preceding
assistant message as `400 tool_call_id  is not found`. The
TOOL_EXCHANGE_ADJACENCY_MESSAGE_PATTERNS only covered Anthropic's
tool_use/tool_result phrasing, so isRecoverableRequestStructureError returned
false, the strict-resend fallback in executeLoopStep never fired, and the
session stayed permanently stuck re-sending the same rejected history every
turn (observed in the field after a manual compaction busted the prompt cache
and forced full revalidation of a latently misordered prefix).

Add the tool_call_id-anchored pattern so the whole recovery chain — strict
projection (adjacency repair, orphan-result drop, synthetic results) plus the
one-shot resend — now also covers the default provider. Covered by classifier
unit tests and an e2e resend-and-recover case.
@changeset-bot

changeset-bot Bot commented Jul 2, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8d27965

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kosong Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 2, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@8d27965
npx https://pkg.pr.new/@moonshot-ai/kimi-code@8d27965

commit: 8d27965

@RealKai42
RealKai42 merged commit 93ec6cb into main Jul 2, 2026
10 checks passed
@RealKai42
RealKai42 deleted the kaiyi/ottawa branch July 2, 2026 05:52
@github-actions github-actions Bot mentioned this pull request Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant