You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(ai): replayed Responses reasoning items are sent without id when the server's item ids have no prefix_suffix shape #55357
With an OpenAI Responses-compatible gateway that issues opaque item ids (for example 8a482c218291d43b), every follow-up turn after a reasoning response fails with HTTP 400:
JSON deserialization for type '...Responses.Input.ReasoningInputItem' was missing required properties including: 'id'.
Cause: itemID() in packages/ai/src/protocols/open-responses.ts only keeps a stored itemId if it contains a _ that is neither the first nor the last character. The gateway's ids don't, so the id is dropped and the replayed reasoning item is sent as {type: "reasoning", summary, encrypted_content} with no id.
The OpenAI spec doesn't define an id format. In openai/openai-openapi (manual_spec), ReasoningItem.id and OutputMessage.id are plain type: string ("The unique identifier of the reasoning content" / "The unique ID of the output message"), with no pattern, prefix or length. Both are in required. msg_abc123 only appears as an example:. A gateway that issues bare ids and validates id on reasoning input is spec-compliant. api.openai.com itself tolerates a missing id, which is why this isn't noticed there.
Related: the same gateway rejected assistant messages without status (also required in the spec). That is already fixed on dev.
Steps to reproduce
Configure a custom provider (npm: @ai-sdk/openai) pointing at a Responses endpoint whose item ids are bare hex and which validates input against the spec.
Send a prompt to a reasoning model, then a second prompt in the same session.
The second request fails with the 400 above.
The stored reasoning part from the failing session:
A server-issued id is replayed verbatim. If none is available, the item is not sent as an invalid reasoning input.
Notes
The current behavior is covered by the test "preserves provider-issued item ids and removes malformed ids without dropping items", which expects 550e8400-e29b-41d4-a716-446655440000 to be dropped as "No prefix separator". That treats the id shape as a validity signal, which the spec doesn't support. Possible fixes: accept any non-empty id that is a safe token, or keep the heuristic and fall back to a generated rs_… id for reasoning items that would otherwise have none. I'm happy to send a PR for whichever you prefer.
Thanks for the detailed report. I reproduced this on 2.0.29, and it still happens on the latest dev (34d8ded0c5).
Setup: a custom @ai-sdk/openai provider pointing at a mock Responses server. The mock issues bare ids (reasoning 8a482c218291d43b, message f00dbeef12345678) and, like your gateway, rejects reasoning input items that have no id. That rejection is mocked, as your report describes it; what I checked is the request OpenCode sends.
The first opencode run succeeds.
The second turn (opencode run -c) fails with JSON deserialization for type 'Responses.Input.ReasoningInputItem' was missing required properties including: 'id'.
In the captured request, the replayed reasoning item is {type: "reasoning", summary: [...], encrypted_content: null} with no id, and the assistant message's id is dropped too.
This matches your analysis of itemID() in packages/ai/src/protocols/open-responses.ts. The id handling there was last changed in #44587. The script below reproduces it.
Activity
opencode-agent commentedon Oct 14, 2026
Thanks for the detailed report. I reproduced this on 2.0.29, and it still happens on the latest
dev(34d8ded0c5).Setup: a custom
@ai-sdk/openaiprovider pointing at a mock Responses server. The mock issues bare ids (reasoning8a482c218291d43b, messagef00dbeef12345678) and, like your gateway, rejects reasoning input items that have noid. That rejection is mocked, as your report describes it; what I checked is the request OpenCode sends.opencode runsucceeds.opencode run -c) fails withJSON deserialization for type 'Responses.Input.ReasoningInputItem' was missing required properties including: 'id'.{type: "reasoning", summary: [...], encrypted_content: null}with noid, and the assistant message's id is dropped too.This matches your analysis of
itemID()inpackages/ai/src/protocols/open-responses.ts. The id handling there was last changed in #44587. The script below reproduces it.Reproduction script (repro.sh)
Run it:
bash repro.sh