Bug type
Behavior bug
Beta release blocker
No
Summary
A openai-codex/* session on Telegram (Codex SDK Responses path) can answer a new, unrelated user message with the exact assistant reply from a previous turn when the previous turn included a function call. Three independent contributors in the openai-codex transport and the lossless-claw plugin combine to leak prior turn state across the session.
Steps to reproduce
- OpenClaw 2026.4.29 with a Telegram channel bound to a
main-style agent and an openai-codex/* model on the ChatGPT subscription path.
- Send a Telegram message that requires a tool call, e.g. a price lookup:
what is the price of SOL. Observe the agent reply with a tool-call result, e.g. $83.95.
- Without restarting the session, send an unrelated knowledge-only question:
what is the capital of the philippines.
- Observe the agent reply with the prior turn's exact assistant text (
$83.95) instead of Manila.
The bug requires the prior turn in the same session to contain function_call + function_call_output items. Pure knowledge-only sequences (e.g. France? → Paris, 2+3? → 5, clear sky color? → Blue) do not reproduce, which has caused the bug to be missed in casual verification.
Expected behavior
A new user message with no semantic relationship to the prior turn yields a fresh assistant reply derived from the new message, not a replay of the previous turn's text.
Actual behavior
Within the same Telegram session, the assistant text from the prior tool-call turn is returned verbatim. The session transcript shows the new user message correctly, but the assistant response is the prior turn's content. The symptom can persist for many subsequent turns (informally "Paris forever") until the session is rotated.
OpenClaw version
2026.4.29 (also affects dist/transport-policy-*.js and dist/openai-transport-stream-*.js shipped on 2026.4.26 and 2026.4.27 per the same-named exports). Release 2026.5.2 was not directly verified; #75154 edited an adjacent code path in 2026.5.2, so the patch sites may have moved.
Operating system
macOS Sonoma (Darwin 25.4.0, arm64). Not OS-specific — bug is in the cross-platform openclaw dist files.
Install method
Global npm install (npm install -g openclaw).
Model
openai-codex/gpt-5.5 (also reproduces on openai-codex/gpt-5.4, openai-codex/gpt-5.4-mini).
Provider / routing chain
openclaw → openai-codex provider → ChatGPT subscription OAuth → https://chatgpt.com/backend-api/codex/responses. The transport code path is createOpenAIResponsesTransportStreamFn in provider-stream-*.js (Codex SDK Responses, not the pi-ai SSE path). lossless-claw is the active conversation-memory plugin.
Logs, screenshots, and evidence
The bug clears completely and stays cleared only when all three of the following empirical patches are applied. Removing any one of them lets the bug regress as soon as a tool-call turn enters a session.
Patch 1 — extensions/openai/transport-policy.ts (resolveOpenAITransportTurnState): the response correlation header x-client-request-id is currently not set turn-scoped. Forwarding the same x-client-request-id across turns in a session correlates with server-side replay behavior on the codex /backend-api/codex/responses endpoint. Patch makes it turn-scoped:
const attempt = String(Math.max(1, ctx.attempt));
+ const requestId = turnId || `${sessionHeaders["x-openclaw-session-id"] ?? "session"}:${attempt}`;
...
return {
headers: {
...sessionHeaders,
+ "x-client-request-id": requestId,
"x-openclaw-turn-id": turnId,
"x-openclaw-turn-attempt": attempt,
},
...
};
(The x-openclaw-turn-id / x-openclaw-turn-attempt headers from the #73963 fix are preserved.)
Patch 2 — extensions/openai/transport-stream.ts (Codex Responses sanitizer + replay flags):
const OPENAI_CODEX_RESPONSES_UNSUPPORTED_PARAMS = [
...
"metadata",
+ "prompt_cache_key",
];
...
- const shouldReplayReasoningItems = <existing-condition>;
+ const shouldReplayReasoningItems = false;
- const shouldReplayResponsesItemIds = <existing-condition>;
+ const shouldReplayResponsesItemIds = model.provider !== "openai-codex";
The prompt_cache_key addition extends the same allowlist that #73963 used for metadata. The codex /backend-api/codex/responses endpoint does not honor prompt_cache_key semantics in the same shape as api.openai.com/v1/responses; sending it can produce server-side caching of the wrong shape. Disabling reasoning-item replay and Responses item-ID replay specifically for openai-codex prevents prior-turn item IDs from being passed back to the server in subsequent turns.
Patch 3 — ~/.openclaw/openclaw.json plugins.entries["lossless-claw"].config.ignoreSessionPatterns: entries like agent:main:telegram:* do not match across the : separator under lossless-claw's glob syntax, so Telegram session keys of shape agent:main:telegram:direct:<chat_id> are not ignored by LCM. Replacing * with ** matches across : and prevents LCM from ingesting and leaking Telegram session context across turns. (This patch is in lossless-claw config rather than openclaw source; relevant here because the symptom does not fully clear without it.)
A self-contained reapply script that encodes all three patches (with node --check syntax verification per patched file and gateway restart on success) is available on request — happy to PR it as a maintenance utility, or maintainers can derive equivalent fixes inline.
Verification
After applying all three patches on 2026.4.29 and clearing the poisoned LCM state for the affected session keys (one-time, only when symptom is already present):
sqlite3 ~/.openclaw/lcm.db "update conversations set archived_at = datetime('now') where session_key like 'agent:main:telegram:%' and active=1 and archived_at is null;"
The full repro sequence (SOL price → capital of philippines) returns correct Manila and stays correct across many subsequent turns.
Impact and severity
- Affects: any
openai-codex/* session running through Telegram (Codex SDK Responses transport) where prior turns can include tool calls. Telegram is the primary affected channel because long-lived sessions accumulate many tool-call turns.
- Severity: high. Symptom is silent — the agent appears to respond, but with prior-turn content. Indistinguishable from a confused model unless the user notices the duplicate text.
- Frequency: deterministic when the prior turn included a tool call; never reproduces in pure knowledge-only sequences.
Related issues
Additional information
The three causes were isolated empirically: each was patched individually first (each appeared to fix the simple knowledge case), then regressed when a tool-call turn was introduced into the session. All three patches together produce a stable fix across our verification corpus. Maintainers may identify a single deeper root cause that subsumes one or more of these patches; the report is structured to make that easier.
Bug type
Behavior bug
Beta release blocker
No
Summary
A
openai-codex/*session on Telegram (Codex SDK Responses path) can answer a new, unrelated user message with the exact assistant reply from a previous turn when the previous turn included a function call. Three independent contributors in the openai-codex transport and the lossless-claw plugin combine to leak prior turn state across the session.Steps to reproduce
main-style agent and anopenai-codex/*model on the ChatGPT subscription path.what is the price of SOL. Observe the agent reply with a tool-call result, e.g.$83.95.what is the capital of the philippines.$83.95) instead ofManila.The bug requires the prior turn in the same session to contain
function_call+function_call_outputitems. Pure knowledge-only sequences (e.g.France?→Paris,2+3?→5,clear sky color?→Blue) do not reproduce, which has caused the bug to be missed in casual verification.Expected behavior
A new user message with no semantic relationship to the prior turn yields a fresh assistant reply derived from the new message, not a replay of the previous turn's text.
Actual behavior
Within the same Telegram session, the assistant text from the prior tool-call turn is returned verbatim. The session transcript shows the new user message correctly, but the assistant response is the prior turn's content. The symptom can persist for many subsequent turns (informally "Paris forever") until the session is rotated.
OpenClaw version
2026.4.29 (also affects
dist/transport-policy-*.jsanddist/openai-transport-stream-*.jsshipped on 2026.4.26 and 2026.4.27 per the same-named exports). Release 2026.5.2 was not directly verified; #75154 edited an adjacent code path in 2026.5.2, so the patch sites may have moved.Operating system
macOS Sonoma (Darwin 25.4.0, arm64). Not OS-specific — bug is in the cross-platform openclaw dist files.
Install method
Global npm install (
npm install -g openclaw).Model
openai-codex/gpt-5.5(also reproduces onopenai-codex/gpt-5.4,openai-codex/gpt-5.4-mini).Provider / routing chain
openclaw →
openai-codexprovider → ChatGPT subscription OAuth →https://chatgpt.com/backend-api/codex/responses. The transport code path iscreateOpenAIResponsesTransportStreamFninprovider-stream-*.js(Codex SDK Responses, not the pi-ai SSE path). lossless-claw is the active conversation-memory plugin.Logs, screenshots, and evidence
The bug clears completely and stays cleared only when all three of the following empirical patches are applied. Removing any one of them lets the bug regress as soon as a tool-call turn enters a session.
Patch 1 —
extensions/openai/transport-policy.ts(resolveOpenAITransportTurnState): the response correlation headerx-client-request-idis currently not set turn-scoped. Forwarding the samex-client-request-idacross turns in a session correlates with server-side replay behavior on the codex/backend-api/codex/responsesendpoint. Patch makes it turn-scoped:(The
x-openclaw-turn-id/x-openclaw-turn-attemptheaders from the #73963 fix are preserved.)Patch 2 —
extensions/openai/transport-stream.ts(Codex Responses sanitizer + replay flags):The
prompt_cache_keyaddition extends the same allowlist that #73963 used formetadata. The codex/backend-api/codex/responsesendpoint does not honorprompt_cache_keysemantics in the same shape asapi.openai.com/v1/responses; sending it can produce server-side caching of the wrong shape. Disabling reasoning-item replay and Responses item-ID replay specifically foropenai-codexprevents prior-turn item IDs from being passed back to the server in subsequent turns.Patch 3 —
~/.openclaw/openclaw.jsonplugins.entries["lossless-claw"].config.ignoreSessionPatterns: entries likeagent:main:telegram:*do not match across the:separator under lossless-claw's glob syntax, so Telegram session keys of shapeagent:main:telegram:direct:<chat_id>are not ignored by LCM. Replacing*with**matches across:and prevents LCM from ingesting and leaking Telegram session context across turns. (This patch is in lossless-claw config rather than openclaw source; relevant here because the symptom does not fully clear without it.)A self-contained reapply script that encodes all three patches (with
node --checksyntax verification per patched file and gateway restart on success) is available on request — happy to PR it as a maintenance utility, or maintainers can derive equivalent fixes inline.Verification
After applying all three patches on 2026.4.29 and clearing the poisoned LCM state for the affected session keys (one-time, only when symptom is already present):
The full repro sequence (
SOL price→capital of philippines) returns correctManilaand stays correct across many subsequent turns.Impact and severity
openai-codex/*session running through Telegram (Codex SDK Responses transport) where prior turns can include tool calls. Telegram is the primary affected channel because long-lived sessions accumulate many tool-call turns.Related issues
resolveOpenAITransportTurnStatecode path. The fix there scopedmetadataremoval to the codex provider but did not addressx-client-request-idscoping or the codex Responses replay flags.prompt_cache_key. Adjacent: this report extends the unsupported-params list for the codex endpoint, which is the opposite direction.transport-streamcode path for tool-call argument repair; downstream patches may need to re-anchor against new line offsets.Additional information
The three causes were isolated empirically: each was patched individually first (each appeared to fix the simple knowledge case), then regressed when a tool-call turn was introduced into the session. All three patches together produce a stable fix across our verification corpus. Maintainers may identify a single deeper root cause that subsumes one or more of these patches; the report is structured to make that easier.