Repository navigation
Stale assistant progress text is replayed into later prompts #19548
Description
Description
Short description here per template request, there's a collapsible section with the full details (ai generated) below.
In the TUI, the assistant can begin responding to the current prompt and then pivot back to an unrelated earlier task from the same session.
Once a message triggers this, it can be consistently reproduced via undo and then sending the same message again.
Observed with OpenAI gpt-5.4, but the issue appears to be OpenCode prompt-history assembly rather than a provider-specific problem.
Likely related upstream issue: #16612 (Sometimes replies to the previous turn (stale context): keeps repeating an earlier command/answer instead of responding to the latest input). This report adds a deterministic repro, code-path analysis, and a local fix.
Identified issue, verification, and local resolution
Identified issue
The problem turned out to be prompt-history serialization in SessionPrompt.prompt and MessageV2.toModelMessages.
SessionPrompt.prompt assembles the next model call from prior session history. For older assistant turns, MessageV2.toModelMessages was replaying historical assistant text too aggressively. That meant intermediate progress text from a previous task was still present in the prompt for a later unrelated task.
The symptom was not “wrong parent ID” or “provider resumed the wrong response”. In the broken cases, the new user message and parentID were correct, but the model was still being shown stale prior-task assistant text and would re-anchor to it.
The relevant code path is:
packages/opencode/src/session/prompt.ts:SessionPrompt.promptpackages/opencode/src/session/message-v2.ts:MessageV2.toModelMessages
The local fix narrowed historical assistant turns to their last step before serializing them into later prompts:
// packages/opencode/src/session/message-v2.ts
const historic = !!options?.active && msg.info.parentID !== options.active;
for (const part of historic ? laststep(msg.parts) : msg.parts) {
if (part.type === "text") {
assistantMessage.parts.push({
type: "text",
text: part.text,
});
}
if (historic) continue;
// keep full step/tool/reasoning continuity only for the active turn
}That change preserves older assistant turns as history, but stops replaying all of their intermediate progress chatter into future prompts.
Why this matches the user-visible bug
The stale content was typically progress text from the previous task, such as “I’m checkpointing...”, “I’m staging...”, or “The reasoning-core checkpoint is committed.” When that text was still in the serialized prompt for a new unrelated request, the assistant could start on the new request and then slide back into the earlier task.
That also explains why /undo is a strong reproducer without being the root cause: undo makes it easier to put the session back into a state where the most recent surviving prior assistant turn is exactly the stale one that gets replayed.
How this was verified
Verification used three separate checks.
Likely related upstream issue: #16612 Sometimes replies to the previous turn (stale context): keeps repeating an earlier command/answer instead of responding to the latest input.
Probably not the same bug: #10287 Critical bug revert undo messages, which appears to be about incorrect file-state restoration on undo rather than stale prompt history.
- Session export inspection
The exported session data showed assistant messages correctly parented to the latest user turn while still emitting content from an older task. That ruled out a simple parent-link bug.
- Instrumented runtime logging
Session.revert cleanup completed correctly, but the next SessionPrompt.prompt call still serialized model history containing stale assistant text from the previous task. That ruled out the initial undo-race hypothesis.
- Deterministic tests
Two local tests made the issue concrete:
-
packages/opencode/test/session/stale-history.test.tssession.prompt stale history reproduction > keeps only the last step from prior assistant turns- This seeds one completed “reasoning core” turn, then sends a different prompt like “Sketch the finite-state-machine core instead.”
- The model call should include only the final assistant step from the old turn, not the earlier progress text.
-
packages/opencode/test/session/message-v2.test.tstrims historic assistant turns to their last step- This verifies
MessageV2.toModelMessagesdirectly.
The prompt-level repro looked like this:
// packages/opencode/test/session/stale-history.test.ts
expect(calls[0]?.messages).toEqual(
expect.arrayContaining([
{
role: "assistant",
content: [
{ type: "text", text: "The reasoning-core checkpoint is committed." },
],
},
]),
);
expect(calls[0]?.messages).not.toEqual(
expect.arrayContaining([
{
role: "assistant",
content: expect.arrayContaining([
{ type: "text", text: "I’m checkpointing the reasoning core first." },
]),
},
]),
);That is the behavioral distinction that fixed the bug locally.
Local resolution
The local resolution was:
- Keep full assistant continuity only for the active turn.
- For older assistant turns, serialize only the last step instead of replaying all intermediate assistant progress text.
- Add regression coverage in
MessageV2.toModelMessagesand in the end-to-end prompt assembly path.
References:
packages/opencode/src/session/prompt.ts:SessionPrompt.promptpackages/opencode/src/session/message-v2.ts:MessageV2.toModelMessagespackages/opencode/test/session/stale-history.test.tspackages/opencode/test/session/message-v2.test.ts
Let me know if you'd like the full patch - just not sure if it'd be useful to submit a PR.
Plugins
None
OpenCode version
1.3.3-aa82890-dirty (local fork with a couple of tweaks, but unrelated)
Steps to reproduce
- Use the TUI in a longer session with multiple tool-using turns.
- Complete one multi-step task where the assistant emits several progress updates.
- Send a different new prompt.
- The assistant may start on the new prompt, but then continue an older task instead.
This looks like the agent having a Memento moment. For instance you'll tell it to do X, it'll say "I'll do X" and put X0 X1 X2 in the Todo list, read some files, and then say "I've gone ahead and committed W as you requested" - where W was some previous task long done.
Deterministic variant: after reproducing as above once, undo/redo reproduce it consistently.
- Trigger the stale-history behavior once in the TUI.
- Run
/undo. - Resend the same message.
- The stale-task pivot reproduces consistently.
Expected:
The assistant should stay anchored to the current user message and the surviving relevant context.
Actual:
The assistant resumes or continues an older task after beginning a response to the current message.
Screenshot and/or share link
Operating System
NixOS on Linux 6.17
Terminal
kitty
Activity
guidomb commentedon Apr 21, 2026
I have just experienced this issue and this is the third time this happens today. I am also using GPT-5.4 but it seems to me more of a opencode issue than the model.
guidomb commentedon Apr 21, 2026
This seems to be a duplicate of #16612
pedrovhb commentedon Apr 21, 2026
Yeah - the solution described here actually turned out to not be good. I'm still experiencing this too
guidomb commentedon Apr 22, 2026
Yes this is becoming unbearable, it is happening to me in most of the interactions that I have. Just updated to 1.14.20 and still present
dimas-cyriaco commentedon Apr 26, 2026
I’m seeing this same issue.
In my case, it seams to happen when I change the subject of the conversation with a new prompt, OpenCode starts processing the new request correctly, and then suddenly pivots back to a previous prompt that it had already answered, as if stale context from an older turn got replayed into the current one.
What makes this especially confusing is that it often looks correct at first:
From my perspective, this does not feel like a simple model misunderstanding. It feels more like the latest user turn is present, but older assistant/tool/progress state is being injected too aggressively and becomes more salient than the current prompt.
Environment:
1.4.11openai/gpt-5.4NixOS Linux 6.18.23 x86_64github-actions commentedon Jul 3, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.