Skip to content

fix(core): recover malformed tool input#37669

Open
opencode-agent[bot] wants to merge 2 commits into
v2from
raw-tool-recovery
Open

fix(core): recover malformed tool input#37669
opencode-agent[bot] wants to merge 2 commits into
v2from
raw-tool-recovery

Conversation

@opencode-agent

@opencode-agent opencode-agent Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • represent malformed tool arguments as a non-executable tool-input-error with stable call identity, authoritative raw input, provider metadata, and hosted-tool identity
  • durably fail only the malformed call and its originating Step, then give the model protocol-safe feedback containing the raw arguments
  • continue with a new logical recovery Step for at most four automatic retries after the initial malformed response
  • preserve and settle valid sibling calls normally instead of discarding their results or risking duplicate side effects
  • handle provider-specific stream shapes across OpenAI Chat, OpenAI Responses, Anthropic Messages, Gemini, and Bedrock Converse
  • regenerate the current client and legacy JavaScript SDK V2 types for the new public recovery state

Safety

Malformed input is never repaired or executed. Recovery is enabled only for a known, unexecuted tool proposal with stable call identity; generic invalid provider output remains terminal.

Already-started local siblings are awaited and retain their truthful results. Provider-executed identity is preserved from input start through settlement even when later events omit the optional flag, preventing hosted tools from being dispatched locally.

Interrupted streams never enter automatic recovery. Repeated malformed responses stop after five total requests: the initial request plus four recovery retries. Every malformed response remains a durably failed Step rather than being retried as the same physical attempt.

Anthropic hosted-tool recovery lowers synthetic failures to valid tool-specific *_tool_result_error payloads. OpenAI Responses uses the authoritative final arguments even when they differ from streamed deltas or output_item.added is absent.

Tests

  • full packages/ai suite: 344 passed, 29 recorded/live cases skipped
  • packages/core/test/session-runner.test.ts: 133 passed
  • full packages/core suite: 1,341 passed, 6 Mercurial cases skipped
  • bun typecheck passed in packages/ai, packages/core, packages/schema, packages/client, packages/sdk/js, packages/protocol, packages/server, packages/cli, packages/tui, packages/app, packages/opencode, and packages/sdk-next
  • regenerated packages/client and packages/sdk/js outputs; repeated generation produced stable hashes
  • git diff --check

Source discussion: https://slack.com/archives/C0BE69AHCQP/p1784401085221000

Requested by: @StarpTech (Dustin Deus via Slack)

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant