Repository navigation
Codex Desktop replay/fork hides steered user messages and leaves some previous-message bodies expanded #19975
Description
Summary
Codex Desktop appears to have a replay/fork rendering issue for local session history:
- Mid-turn steered/guided user messages are present in the raw session JSONL, but the Desktop UI can omit the user message bubble when replaying the session history or viewing a forked session.
- When replaying, reopening, or forking an existing session, some prior message bodies are not consistently collapsed into the compact
previous messages/earlier messageshistory UI. Instead, individual message bodies from the previous history can remain expanded inline, making the resumed or forked session harder to inspect.
This looks like a UI/session replay bug rather than data loss: the raw JSONL still contains the relevant user messages and history entries.
Environment
- App: Codex Desktop
- Version observed:
26.422.3464.0 - Platform: Windows
- Session source in JSONL metadata:
vscode - CLI version in JSONL metadata:
0.125.0-alpha.3
What I observed
During an active assistant turn, I sent a steering message. The raw session JSONL contains both entries for the message:
{
"type": "response_item",
"payload": {
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "<redacted steering message>\n"
}
]
}
}and:
{
"type": "event_msg",
"payload": {
"type": "user_message",
"message": "<redacted steering message>\n",
"images": [],
"local_images": [],
"text_elements": []
}
}However, when viewing the session in Codex Desktop, the UI may show the steering marker/status area and then the following assistant response, while the actual user bubble is missing.
I also reproduced this around session branching/forking. The forked session JSONL includes:
{
"type": "session_meta",
"payload": {
"id": "<fork-session-id>",
"forked_from_id": "<original-session-id>"
}
}The copied history in the fork still contains the same response_item user message and event_msg:user_message records. A thread_rolled_back event appears after the copied history and before the new branch turn:
{
"type": "event_msg",
"payload": {
"type": "thread_rolled_back",
"num_turns": 1
}
}In the Desktop UI, that forked/replayed history can still omit the guided/steered user bubble even though the raw data is present.
Separately, historical message content around replay/fork/resume is not consistently collapsed. I expected prior history to be hidden behind the compact previous messages/earlier messages affordance. Instead, some individual message bodies from the prior history can remain expanded inline, including normal assistant/user text and surrounding historical context. The core problem here is not command output verbosity; it is that some message bodies from previous history are not collapsed as previous-history content.
Expected behavior
- If the JSONL contains a user steering message as
response_itemwithrole=userand/orevent_msg:user_message, the Desktop replay should render the corresponding user bubble. - Forked sessions should render copied historical steered/guided messages the same way the original session does.
- When reopening, replaying, or forking a long session, prior message bodies that belong to collapsed history should remain behind the normal
previous messages/earlier messagesUI instead of expanding inline.
Actual behavior
- The raw JSONL contains the steered/guided user message, but the Desktop replay/fork UI can omit the user bubble.
- Forked session history appears to be reconstructed around copied history plus
thread_rolled_back, and that path seems to lose some rendering state for steered/guided messages. - Some previous-history message bodies can remain expanded inline instead of being collapsed into the compact previous-message/history block.
Notes
I found related public issues around steering, queued prompts, compaction, conversation-state desync, and fork/resume history, but I did not find an exact duplicate for this specific Desktop replay symptom where the raw user message exists and only the rendered bubble is missing.
Related examples I found:
- Steer conversation and compacting issue #9734
- Non-steered queued tasks sometimes randomly spontaneously become "steered", stopping any previously on-going tasks #17876
- Codex Desktop stuck after “Error submitting prompt/message”; delayed duplicate prompts became steered and Stop did not work #19951
- Desktop thread can enter persistent conversation-state desync after request_user_input in Default mode #10952
- fix(tui): restore remote resume and fork history #14930
The key diagnostic point is that this does not appear to be session data loss. It appears to be a renderer/replay conversion issue for Desktop session history, especially around steered/guided messages, fork/rollback reconstruction, and previous-history message body collapse state.
Activity
github-actions commentedon Apr 28, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
[-]Codex Desktop replay/fork hides steered user messages and does not collapse long tool logs[/-][+]Codex Desktop replay/fork hides steered user messages and leaves previous-message history expanded[/+][-]Codex Desktop replay/fork hides steered user messages and leaves previous-message history expanded[/-][+]Codex Desktop replay/fork hides steered user messages and leaves some previous-message bodies expanded[/+]Necmttn commentedon Jun 21, 2026
Replay/fork rendering should be derived from immutable message records, not from the current collapse state.
Each message part needs role, source surface, turn id, parent id, steered/guided flag, and raw transcript offset. The renderer can collapse previous-history groups for readability, but user-authored steering messages should remain addressable and visible as first-class transcript events.
Generated with ax.
StreamVi commentedon Aug 24, 2026
I reproduced a stronger form of this on Windows Desktop where almost the entire visible history of a long active turn disappeared after reopening the task.
Environment
26.818.5229.0Reproduction
Diagnostic evidence
status: active.read_threadcall found only oneinProgressturn containing the first user message and a few early items.nextCursor: nullandhasMore: false, even though many later steering messages and assistant responses had occurred.navigate_to_codex_pagereturnednavigated: true, but navigating away and back did not restore the missing transcript.This appears consistent with the issue's missing steered-message replay, but the impact is broader: after reopening, the user can lose the visible audit trail for nearly the whole active turn, and the history API reports that no older page exists.
Expected behavior
Every accepted steering/follow-up message and its resulting assistant output should be durably represented in the replayable thread history. If an active turn cannot be fully rehydrated, Desktop should fetch/reconcile it from canonical history or show an explicit recovery error; it should not return
hasMore: falsefor an incomplete projection.No private thread IDs, prompts, project names, or local paths are included here.
magiclinesofcode commentedon Sep 25, 2026
Reproduced on 2026-09-25 with Windows Codex Desktop 26.917.8451.0 connected over Remote SSH to a Mac app-server 0.157.0. The same Mac app-server also owns iOS Remote, so there is no competing thread writer in this reproduction.
During a long active turn, iOS submitted a follow-up accepted by the server as thread/queue/add followed by turn/steer. The iOS app displays the user message bubble. The canonical rollout and thread_history_1.sqlite both contain it as a userMessage item within that active turn (clientId is null). The history projection cursor is at the end of the rollout. Codex Desktop's task-history read API returns the userMessage and the following agent response. The Windows desktop UI displays the agent response and subsequent image previews but omits only the steered user message bubble.
Switching to another task and back, and reconnecting only the Windows SSH transport, did not restore the bubble. A prior Windows-originated message that started its own turn, with a non-null clientId, appeared on both devices. This is a user-message rendering/replay failure, not message loss or stalled history projection, and appears to be the same failure reported in #19975 on a current desktop release.
Please render persisted userMessage items that are steered into an active turn, including messages originating from iOS Remote. I can provide sanitized event IDs and timestamps privately if useful.
nie2894 commentedon Oct 11, 2026
Windows 26.1007.2314.0:运行中追加的 userMessage 被转换为仅有 steered 标记
补充本版本的诊断与合成复现。测试输入均为合成资料,不包含用户原对话、截图、账号、线程ID或本机路径。
当前实测
安装版转换逻辑的最小复现
只读检查当前安装版:本地会话visibleTurnEntries的preserveServerUserMessages为false,aeon路径为true。userMessage转换分支存在以下行为:
从安装版抽取该case分支和去重辅助函数,在独立Node VM中运行;展示构造、策略过滤等非目标辅助函数用桩替代。因此这是精确分支复现,不是整个运行中应用的端到端复现。
合成输入为一段文字和三张虚拟图片:原分支输出仅steered,文字false、图片0。候选条件让未去重的null-client服务端消息继续渲染用户气泡后,输出user-message(文字true、图片3)+steered。
8个合成用例通过:空clientId图片追加、空clientId纯文本追加、非空clientId追加、preserve=true、首条消息去重、已匹配steering去重、初始clientId去重、助手回复后合法重复提问。
建议维护者核对
请在产品源码中保留未被首条输入或steering消息去重的持久化userMessage;不要把clientId为空作为隐藏气泡的依据。维持首条/steering去重、特殊消息过滤和搜索锚点一致性。检查本地会话preserveServerUserMessages=false的历史兼容目的,避免简单全局切换该标志造成重复。
候选修正只在离线提取副本上验证,未修改签名安装包、原始历史或客户端数据库,未验证手机运行时。需要维护者提供正式修复或受支持的无损恢复入口,并验证原消息文字和图片在Windows及手机原时间线均可见。
vgeshel commentedon Oct 20, 2026
Additional reproduction on Codex Desktop 26.1013.40934, observed October 19, 2026 (America/Los_Angeles). This instance concerns a cloud-backed Codex chat viewed in Desktop. The operating system was not collected.
Observed behavior
Two follow-up user prompts disappeared from the displayed conversation, while the assistant's separate final answers appeared consecutively in one response block. This makes the visible history look as though the assistant answered without the intervening corrections.
A user-provided screenshot shows the first user prompt, one work/activity block, and both final answers, but omits the two intervening user prompts. The screenshot and private conversation text are not attached here.
Stored record versus displayed history
The Codex app's
read_threadtool returned one completed turn containing three distinctuserMessageitems and two distinctagentMessageitems withphase: final_answer, in this order (commentary and tool items omitted):Both omitted user messages retained their complete text and distinct message IDs in that result. The visible Desktop timeline instead showed user A followed by answer A and answer B together, with B and C absent.
This establishes a discrepancy between the readable stored chat record and the rendered conversation. It does not establish deletion from storage. This investigation used
read_thread; it did not inspect the desktop renderer, local rollout files, or local databases.Observed sequence, not a clean minimal reproduction
read_thread: the latter contains the intervening user messages, while the UI omits them and combines the final answers.No fork or replay action was identified as a required trigger in this occurrence. Persistence across an app restart and recovery through Queue mode have not been tested.
Expected behavior
Render every accepted user-authored message at its chronological position, including follow-ups inside a turn, and retain the separation between assistant answers and intervening corrections. A single turn containing multiple user inputs and final-answer items should not become a transcript that omits those inputs.
The previously discussed
preserveServerUserMessages/null-clientIdrendering path is a possible related mechanism, but it has not been verified on this installation. Private prompts, session IDs, repository details, and credentials are omitted from this report.sunfloweeeeer commentedon Oct 21, 2026
Additional observed case on macOS, possibly related to this issue.
Environment:
Observed behavior:
A short follow-up was submitted near the end of an active assistant turn. Its user-message bubble is absent from the desktop conversation. The assistant's first answer and its answer to the follow-up appear consecutively, with no user message separating them. The user provided a screenshot showing this and reported that closing/reopening the app did not restore the missing bubble.
Read-only verification:
Sanitized relative timeline:
This case establishes that the follow-up was persisted and answered; it is not a demonstrated loss of message data. The same-turn rendering/replay path is a candidate investigation area, not a confirmed code-level root cause. No fork operation is required by the observed sequence. A deterministic minimal reproduction has not been established.
Expected: render every persisted user message in chronological order, including user input accepted via steering, and preserve those bubbles after reopening the chat.
No conversation text, screenshot, raw logs, private paths, account details, or session identifiers are included in this public comment.