Codex Desktop replay/fork hides steered user messages and leaves some previous-message bodies expanded

Open 💬 3 comments Opened Apr 28, 2026 by libimor
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

Codex Desktop appears to have a replay/fork rendering issue for local session history:

  1. 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.
  2. When replaying, reopening, or forking an existing session, some prior message bodies are not consistently collapsed into the compact previous messages/earlier messages history 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_item with role=user and/or event_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 messages UI 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:

  • #9734
  • #17876
  • #19951
  • #10952
  • #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.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #19042
  • #18508

Powered by Codex Action

Necmttn · 2 months ago

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 · 4 days ago

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

  • Codex Desktop for Windows, AppX package 26.818.5229.0
  • Local Codex task backed by a WSL workspace
  • One long-running assistant turn with many user steering/follow-up messages

Reproduction

  1. Start a task and keep the same assistant turn active for a long time.
  2. Send multiple follow-up/steering messages while that turn is still running.
  3. Later reopen the task, or navigate to another task and back.
  4. The task opens, but the accumulated conversation history is absent; only the beginning may be available.

Diagnostic evidence

  • The task was still returned by the Desktop thread list with the correct title and status: active.
  • A direct read_thread call found only one inProgress turn containing the first user message and a few early items.
  • The page metadata simultaneously returned nextCursor: null and hasMore: false, even though many later steering messages and assistant responses had occurred.
  • navigate_to_codex_page returned navigated: true, but navigating away and back did not restore the missing transcript.
  • The active assistant still had enough effective context to reconstruct what had been discussed, so this looked like a retained-history/replay projection failure rather than the task itself being deleted.

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: false for an incomplete projection.

No private thread IDs, prompts, project names, or local paths are included here.