Repository navigation
Description
Description
On the stock OpenAI Responses path (@ai-sdk/openai, not the bundled openai-compatible / copilot adapter), a multi-turn GPT-5 session can silently jump back to an older task instead of replying to the most recent user message.
This does not always throw an API error. Sometimes the next assistant turn just continues stale context.
This looks related to the existing store:false / Responses replay bug family (#7724, #2941, #4426, #4445, #8746), but the symptom here is different: instead of rs_* not found, the model continues an older thread.
This also appears different from #17926. That issue is about the bundled Responses adapter for @ai-sdk/openai-compatible; this repro is on the stock OpenAI path.
Concrete example
I debugged a local failing session where:
- the user sends
commit - the assistant correctly starts commit-related work
- on the next assistant turn, the model switches back to an older task/topic instead of continuing the commit flow
In this repro, the wrong assistant message still has the correct latest parentID, so the session/message ordering appears correct. The stale jump seems to be caused by replayed model context, not by selecting the wrong session/message.
Corrected hypothesis
My original hypothesis was too broad: it treated reasoning.encrypted_content in a store:false request as suspicious by itself.
That is probably wrong.
OpenAI's reasoning docs say that in stateless mode (store:false or zero data retention), clients must still retain and resend reasoning items, and must request reasoning.encrypted_content via include so those reasoning items can be replayed on future requests.
So the bug is not simply "encrypted_content exists in the request". For current tool-call follow-ups and current-turn continuation, encrypted_content is expected and needed.
The likely bug is narrower:
- stale reasoning from assistant turns before the latest user message may be replayed into a new request
- replay item IDs and encrypted reasoning state have different semantics and should not be treated as the same thing
- request/message normalization should remove stale reasoning before the latest user turn while preserving relevant/current reasoning for valid Responses continuation
In other words: keep hidden reasoning where OpenAI requires it, but do not replay stale hidden reasoning from older tasks into a new user turn.
Relevant code paths
The OpenAI request path in packages/opencode/src/provider/provider.ts sanitizes response item IDs before sending the final POST body:
if (model.api.npm === "@ai-sdk/openai" && opts.body && opts.method === "POST") {
const body = JSON.parse(opts.body as string)
const isAzure = model.providerID.includes("azure")
const keepIds = isAzure && body.store === true
if (!keepIds && Array.isArray(body.input)) {
for (const item of body.input) {
if ("id" in item) {
delete item.id
}
}
opts.body = JSON.stringify(body)
}
}The safer layer for stale reasoning handling appears to be message normalization before the SDK converts model messages into Responses input: remove old assistant reasoning parts before the latest user message for @ai-sdk/openai + store:false, but preserve latest-turn reasoning and valid tool-call continuation.
Likely fix direction
A fix should probably:
- strip OpenAI response item IDs where needed for stateless replay compatibility
- drop stale assistant reasoning parts before the latest user turn on
store:false - preserve latest/current reasoning so GPT-5 Responses can continue tool-call flows correctly
- avoid orphaning following tool results when stripping reasoning would otherwise remove an assistant message entirely
- add regression coverage at both the transform/message-normalization layer and the final OpenAI Responses request shape
This matches OpenAI's stateless Responses guidance better than treating all encrypted reasoning as stale.
Steps to reproduce
I do not have a tiny deterministic repro yet, but the pattern is:
- Use stock OpenAI GPT-5 on the Responses path
- Ensure requests are using
store:falseor equivalent zero-retention behavior - Let the assistant perform at least one tool-using task
- Send a short follow-up that changes task, for example
commit - Occasionally, after the tool step, the next assistant turn resumes an older task/thread instead of the latest user request
Expected behavior
The assistant should continue the latest user request.
Actual behavior
The assistant sometimes replies to or continues an older task with no API error.
Additional context
I saw this on a local repro session where the stale turn resumed an earlier topic ("Clarifying code parameters") immediately after the user sent commit.
Related broader stale-context issues:
- Keep getting "Item with id 'rs_xxxxx' not found. Items are not persisted when 'store' is set to false" and out of context #7724 explicitly mentions
out of contextalongside thestore:falsereplay errors - gpt-5-codex failure: AI_APICallError: Item 'rs_... of type 'reasoning' was provided without its required following item. #2941 and related issues describe follow-up / continue-session failures in the same Responses replay area
- Sometimes replies to the previous turn (stale context): keeps repeating an earlier command/answer instead of responding to the latest input #16612 and Stale assistant progress text is replayed into later prompts #19548 report broader stale-task drift that may also involve visible assistant progress text, tool output, or todo bookkeeping replay. This issue is specifically about the stock OpenAI Responses/stateless replay path.
Activity
github-actions commentedon Apr 4, 2026
This issue might be a duplicate of existing issues. Please check:
SessionPrompt.prompt/MessageV2.toModelMessages, rather than the OpenAI Responses replay payload. The root cause hypotheses differ, but the observable behavior is the same — worth cross-referencing to confirm these are distinct bugs.store: false/ Responses API / multi-turn area, but targets the bundled@ai-sdk/openai-compatibleadapter namespace mismatch (you already distinguish this in your report).Cleroth commentedon Apr 4, 2026
Probably related: #16612 and #19548
[-][Bug] OpenAI Responses with store:false can silently resume an older task instead of the latest user turn[/-][+][Bug] OpenAI Responses store:false can replay stale reasoning from older turns[/+]Svtter commentedon Apr 25, 2026
Your hypothesis about stale reasoning in
store:falsemode is correct. I identified the specific code paths — see full analysis in #24190: #24190 (comment)The two most relevant root causes for your OpenAI case:
transform.ts:508-516—include: ["reasoning.encrypted_content"]only set in variant options, so default mode never requests encrypted reasoning contentconvert-to-openai-responses-input.ts:208-237— Thestore:falsebranch doesn't properly handle reasoning items with empty summary text but validencrypted_contentVercel AI SDK fixed similar issues in vercel/ai#12869 and vercel/ai#14418, but opencode's custom converter has the same bugs.
rekram1-node commentedon Apr 30, 2026
This is not a bug, we match the implementation of codex.
Cleroth commentedon Jun 1, 2026
It does actually seem to be a bug in codex. After implementing the above fix, I haven't experienced this ever again in the two months that followed, despite having encountered it fairly often before it.
Many people report codex/gpt occasionally replying to a previous message. They chalk it up to the model being stupid but it seems to be bug in harnesses instead.