Codex Mobile: queued message disappears after app background/thread reload

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

Summary

A queued message in Codex Mobile can disappear after the app is backgrounded and the thread is reloaded. This is user-authored input loss: the message was accepted by the UI as Queue rather than Steer, but after returning to the app there was no visible way to resend, recover, or inspect the queued draft.

Observed

Observed on Android on 2026-05-30 while a goal was active.

  1. A Codex Mobile thread was in the middle of an active goal / long-running turn.
  2. I typed a follow-up message and tapped Queue, not Steer.
  3. I left/backgrounded the app before the active work consumed that queued message.
  4. I came back later.
  5. The thread took a while to load.
  6. Once it loaded, the queued message was gone.
  7. There was no visible resend/retrieve/recover affordance.

Expected

Queued messages should either be durable or explicitly recoverable:

  • remain visible across background/resume and thread reload until sent or canceled
  • survive while a goal/turn is active
  • show whether the queued message is local-only, server-synced, sent, canceled, or failed
  • provide a retry/recover path if the app could not submit or restore the queued message

Actual

The queued message disappeared silently after reload.

Related issues I found

These look adjacent, but I did not find an exact duplicate for mobile queued input disappearing after app background/thread reload:

  • openai/codex#22746 reports Codex Mobile not supporting steer/queue messages. This issue is about the newer mobile Queue UI accepting the message and then losing it after reload.
  • openai/codex#23100 reports queued messages only processing when the project is in focus. This issue is about mobile state loss after backgrounding/reloading.
  • openai/codex#19151 reports queued prompts after a queued /new getting dropped in CLI.
  • openai/codex#23615 proposes Queue/Steer/Stash recoverability concepts.
  • openai/codex#22895 and openai/codex#14213 cover queued-message editing / queue position behavior in Desktop/TUI.
  • openai/codex#13892 covers TUI confusion between queued follow-ups and steer state.

App-server/API note

I am not sure whether the app-server is intended to own queued messages. From a quick scan of the public v2 app-server surface, I see turn/start for adding user input and beginning a turn, and turn/steer for adding input to an already in-flight regular turn. I did not see a public durable queued-message or queued-draft primitive.

If mobile queue state is currently client-only, mobile should persist it locally and reconcile/replay it on reconnect. A stronger cross-client fix might be an app-server-backed queued prompt/draft API, for example:

  • thread/queuedMessages/list
  • thread/queuedMessages/add
  • thread/queuedMessages/update
  • thread/queuedMessages/delete
  • notifications for queued-message state changes

Stable client IDs / idempotency would let mobile safely retry after reconnect without duplicating queued user input.

Why this matters

Queued messages are often written while Codex is doing long-running work. Losing them silently on mobile makes it unsafe to queue important follow-up instructions before switching apps or waiting for a goal to continue.

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 2 months ago

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

  • #25244

Powered by Codex Action

etraut-openai contributor · 2 months ago

This isn't specific to goals or to the mobile app. Currently, queued messages are not persisted and are handled client-side, so if you unload the thread in the client or quit the client, the queued message will not be sent and will be lost. We're looking at adding server-side queuing to address this.

tzarebczan · 2 months ago

Awesome, glad to hear that!

orionflame · 1 month ago

This is unacceptable, not only it loses the last sent prompt, I just saw it clears the entire queue so then when you come back, you see none of the queued prompts were done. How hard it is to do this, they are not even on the server side, so it should be easy to save the queue locally. OpenAI should provide limit reset anytime this happens. It causes loss of work.

DragonWork · 23 days ago

Unfortunately this is still an issue and should be really prioritized. I see myself use steer rather than queue (despite latter being more logical to not disturb current work), just so the model receives the next prompt. The queue is just unreliable and more often than not loses the prompt.

Vosatorp · 18 days ago

Additional reproduction from the iOS remote-control surface, observed on 2026-08-09.

Environment:

  • Codex Desktop 26.803.41515 (build 6321)
  • macOS execution host
  • iPhone Codex/ChatGPT mobile remote control
  • Desktop setting: followUpQueueMode = "queue"

This extends the original report because the loss occurred without an intentional mobile background/thread reload between enqueue and disappearance:

  1. A long Desktop turn was actively running.
  2. On iPhone, the user dictated a roughly five-minute follow-up.
  3. Transcription completed successfully and the message was submitted using Queue.
  4. Mobile displayed the item as queued.
  5. When the active Desktop turn completed, the queued item disappeared.
  6. No next user turn started, the text never appeared in thread history, and there was no failed/retry/recover state.

This happened twice on the same day with two separately dictated long follow-ups.

Read-only local inspection after the event found:

  • no matching queued item in the Desktop owner's persisted queued-follow-ups state or its backup;
  • no matching user turn in the local thread/session history;
  • no recoverable copy in the local state database/WAL;
  • the follower queue path can update transient UI state before owner synchronization is durably acknowledged, while a failed synchronization path does not leave a durable follower-side outbox.

That is consistent with the client-side, non-persisted queue model confirmed above, but it shows an additional failure mode: the UI can acknowledge Queued and still lose the input even when the user did not deliberately unload the mobile thread.

In one occurrence, a remote-control credential expiry/refresh boundary happened within seconds of the active turn completing. This is only a correlation, not a claimed root cause, but may help narrow internal telemetry.

Suggested invariant:

  • do not show Queued until a durable owner/server acknowledgement exists;
  • persist an originating-client outbox before enqueue;
  • retain the transcribed text until delivery is acknowledged;
  • use stable queue-item IDs/idempotent retries;
  • after reconnect/relaunch, reconcile to pending / accepted / delivered / failed;
  • on failure, keep the text visible with Retry and Copy instead of clearing it.

Exact private thread/turn IDs and the narrow timestamp window are available for a private /feedback upload; prompt contents and identifiers are intentionally omitted here.