openclaw - ✅(Solved) Fix [Bug]: Successful assistant replies can be missing from the active transcript, causing later turns to re-answer old prompts [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#76990Fetched 2026-05-04 04:59:40
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
2
Author
Timeline (top)
cross-referenced ×4commented ×1

A successful embedded agent run can produce visible assistant text in the run trajectory while failing to persist an equivalent visible assistant turn in the active session transcript branch. Later turns then see prior user messages as unanswered and may answer multiple previous questions again before addressing the latest prompt.

This is distinct from a pure channel-delivery problem: the reply text exists in the run artifacts and was visible to the user, but the persisted conversation state does not retain the corresponding visible assistant turn on the branch used for future context assembly.

Root Cause

Future context assembly should not treat already answered user messages as still unanswered merely because the visible assistant reply was present only in trajectory artifacts or channel delivery state.

Fix Action

Fix / Workaround

Local source-level mitigation that verified the mechanism:

Validation on the local mitigation:

PR fix notes

PR #77033: fix: prevent stale transcript replay

Description (problem / solution / changelog)

Summary

  • avoid duplicating normal WebChat agent-run assistant turns by treating Pi message_end persistence as canonical
  • repair missing visible assistant transcript turns only after comparing against the canonical post-prompt assistant message, not delivery chunks
  • prevent stale context-overflow retries from replaying an already-persisted inbound message, and persistently remove only safe orphan transcript leaves

Root Cause

Pi persists finalized assistant messages from message_end through SessionManager.appendMessage(). OpenClaw fallback paths were mixing that canonical transcript with live delivery text/chunks, which could either duplicate already-persisted assistant turns or retry from stale transcript state after compaction.

Verification

  • pnpm test src/agents/pi-embedded-runner/run/attempt.test.ts src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts src/gateway/server-methods/chat.directive-tags.test.ts
  • git diff --check origin/main...HEAD
  • Testbox pnpm check:changed: https://github.com/openclaw/openclaw/actions/runs/25296951566

Fixes #76804 Fixes #76424 Fixes #76886 Fixes #76990

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts (modified, +83/-0)
  • src/agents/pi-embedded-runner/run.ts (modified, +18/-2)
  • src/agents/pi-embedded-runner/run/attempt.test.ts (modified, +347/-0)
  • src/agents/pi-embedded-runner/run/attempt.ts (modified, +151/-5)
  • src/gateway/server-methods/chat.directive-tags.test.ts (modified, +61/-1)

Code Example

user -> assistant-visible-reply -> user -> assistant-visible-reply

---

Sanitized evidence shape from the failing session:

trajectory run A:
  finalStatus: success
  trace.artifacts.data.assistantTexts: [<visible answer for user prompt A>]

session transcript active branch after run A:
  user <prompt A>
  assistant <tool_use/runtime entry>
  toolResult <tool result>
  # missing: assistant <visible answer for prompt A>

later session transcript / prompt context:
  user <prompt A>
  user <prompt B>
  user <prompt C>
  ...

later assistant output:
  <answers prompt A, prompt B, prompt C again before addressing latest prompt>

---

pnpm vitest run src/agents/pi-embedded-runner/run/assistant-transcript-repair.test.ts
# 1 file passed, 4 tests passed

pnpm vitest run src/agents/pi-embedded-runner/run/assistant-transcript-repair.test.ts src/agents/pi-embedded-runner/run/attempt.test.ts
# 3 files passed, 266 tests passed
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

A successful embedded agent run can produce visible assistant text in the run trajectory while failing to persist an equivalent visible assistant turn in the active session transcript branch. Later turns then see prior user messages as unanswered and may answer multiple previous questions again before addressing the latest prompt.

This is distinct from a pure channel-delivery problem: the reply text exists in the run artifacts and was visible to the user, but the persisted conversation state does not retain the corresponding visible assistant turn on the branch used for future context assembly.

Steps to reproduce

Observed on a channel-backed auto-reply session using the embedded PI runner and Codex Responses provider:

  1. Run OpenClaw 2026.5.2 with a messaging-channel auto-reply agent using openai-codex/gpt-5.5.
  2. Send several normal conversational questions in one long-lived session, including turns that use tools or runtime/context events.
  3. After each run completes successfully, compare the run trajectory with the session transcript file.
  4. In the failing session, .trajectory.jsonl contained successful trace.artifacts / model.completed data with non-empty assistantTexts for individual user prompts.
  5. The corresponding session .jsonl active branch contained the user prompt and assistant tool-use/tool-result/runtime entries, but no matching visible assistant text turn for some completed runs.
  6. Send another later prompt in the same session.
  7. The assembled context can now contain a backlog of consecutive or effectively unanswered user turns, and the assistant may reply with answers to earlier already-answered questions before or instead of the newest prompt.

Expected behavior

Every successful run that yields user-visible assistant text should leave the active persisted transcript branch in a state equivalent to:

user -> assistant-visible-reply -> user -> assistant-visible-reply

Future context assembly should not treat already answered user messages as still unanswered merely because the visible assistant reply was present only in trajectory artifacts or channel delivery state.

Actual behavior

The affected session had successful run artifacts with assistantTexts, but later transcript snapshots omitted the matching visible assistant turns on the active branch. Subsequent model prompts therefore included prior user messages without their replies, and the assistant produced omnibus/stale answers covering earlier questions again.

A separate orphan/queue merge issue can make this worse, but it is not sufficient to explain the whole symptom: even without relying on the channel transcript, the run trajectory had the assistant text and the active transcript branch did not.

OpenClaw version

OpenClaw 2026.5.2 (8b2a6e5 observed locally)

Operating system

Ubuntu 25.10, Linux x86_64

Install method

Source checkout / live service build from openclaw/openclaw, gateway under systemd user service

Model

openai-codex/gpt-5.5

Provider / routing chain

OpenClaw messaging auto-reply -> embedded PI runner -> openai-codex provider / Codex Responses

Additional provider/model setup details

Observed in a WhatsApp-backed CLO-style agent session, but the failing state is in the shared embedded runner transcript/session layer rather than WhatsApp routing. Private channel identifiers, session identifiers, exact user content, and local paths are intentionally omitted.

Logs, screenshots, and evidence

Sanitized evidence shape from the failing session:

trajectory run A:
  finalStatus: success
  trace.artifacts.data.assistantTexts: [<visible answer for user prompt A>]

session transcript active branch after run A:
  user <prompt A>
  assistant <tool_use/runtime entry>
  toolResult <tool result>
  # missing: assistant <visible answer for prompt A>

later session transcript / prompt context:
  user <prompt A>
  user <prompt B>
  user <prompt C>
  ...

later assistant output:
  <answers prompt A, prompt B, prompt C again before addressing latest prompt>

Local source-level mitigation that verified the mechanism:

  • After a successful embedded run, inspect extracted visible assistantTexts.
  • If there is no equivalent visible assistant message reachable after the prompt leaf on the active transcript branch, append a normal visible assistant message under the session lock.
  • Add regression coverage for: no-op when already persisted, append when missing, ignore whitespace-equivalent duplicates, and no-op for missing manager/session path.

Validation on the local mitigation:

pnpm vitest run src/agents/pi-embedded-runner/run/assistant-transcript-repair.test.ts
# 1 file passed, 4 tests passed

pnpm vitest run src/agents/pi-embedded-runner/run/assistant-transcript-repair.test.ts src/agents/pi-embedded-runner/run/attempt.test.ts
# 3 files passed, 266 tests passed

Impact and severity

High for affected channel-backed agents. The user sees the agent answer old questions again, bundle multiple previous answers into a later reply, or appear to ignore the latest message. It also makes transcript/debugging state misleading because the trajectory proves a reply existed while the session branch used for future context does not.

Additional information

Related issues in the same stale-reply/transcript cluster, but not exact duplicates of this failure mode:

  • #76875 reports agents prioritizing previous messages after 2026.5.2, but lacks the transcript/trajectory proof point.
  • #76888 covers queued/orphaned user-message merge causing stale replies.
  • #76968 covers orphaned user repair leaving the persisted transcript out of sync and has PR #76969 open.
  • #76886 covers Codex app-server mirrored final replies being lost from the active branch; this report is the embedded PI runner / trajectory assistantTexts version of the same class of invariant failure.

Suggested invariant for the fix: once a run successfully generates visible assistant text, exactly one equivalent visible assistant turn should be present on the active persisted transcript branch before any later user message can be appended under that branch.

extent analysis

TL;DR

The issue can be fixed by ensuring that a successful embedded agent run appends a visible assistant message to the active transcript branch if it's missing, to maintain a consistent conversation state.

Guidance

  • Verify that the assistantTexts in the run trajectory are correctly extracted and processed after a successful run.
  • Check the session transcript active branch for the presence of a visible assistant turn after each run, and append one if it's missing.
  • Ensure that the appended assistant message is correctly linked to the corresponding user prompt and tool/runtime entries.
  • Review the local mitigation code and test coverage to ensure that it correctly handles cases where the assistant message is already persisted, or where there are duplicate or whitespace-equivalent messages.

Example

// Example of appending a visible assistant message to the active transcript branch
if (runStatus === 'success' && !assistantTurnPresent) {
  const assistantMessage = extractAssistantText(runArtifacts);
  appendAssistantMessageToTranscript(assistantMessage, transcriptBranch);
}

Notes

The provided local mitigation code and test coverage suggest that the issue can be resolved by ensuring that the active transcript branch is updated correctly after each successful run. However, further review and testing may be necessary to ensure that the fix is comprehensive and does not introduce any regressions.

Recommendation

Apply the workaround by appending a visible assistant message to the active transcript branch if it's missing, as demonstrated in the local mitigation code. This should ensure that the conversation state is consistent and that the assistant responds correctly to user prompts.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Every successful run that yields user-visible assistant text should leave the active persisted transcript branch in a state equivalent to:

user -> assistant-visible-reply -> user -> assistant-visible-reply

Future context assembly should not treat already answered user messages as still unanswered merely because the visible assistant reply was present only in trajectory artifacts or channel delivery state.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING