app-server websocket shared-thread turns complete but rollout never materializes, so sibling thread/resume fails with "no rollout found"
What issue are you seeing?
On codex-cli 0.117.0, a shared websocket codex app-server can run a real user turn to completion, but
the rollout file is never materialized on disk.
As a result:
thread/readwithincludeTurns: falseworksthread/readwithincludeTurns: truefails- sibling
thread/resumefails withno rollout found for thread id ...
Environment
- Codex CLI:
0.117.0 - Release tag:
rust-v0.117.0 - Release commit:
4c70bff480af37b1bf1a9b352b8341060fe55755 - Transport: websocket app-server
- Launch:
codex app-server --listen ws://127.0.0.1:9891
What steps can reproduce the bug?
Repro
- Start a shared websocket app-server.
- Client A connects and calls
initialize. - Client A calls
thread/start. - Client A calls
turn/startwith:
```json
{
"threadId": "<thread-id>",
"input": [
{
"type": "text",
"text": "Please reply with exactly the word materialized.",
"text_elements": []
}
]
}
- Wait for:
- item/started for userMessage
- item/completed for userMessage
- assistant reply
- turn/completed
- On the same client, call:
- thread/read with includeTurns: false
- thread/read with includeTurns: true
- On sibling Client B, call:
- thread/resume for the same thread id
- Check the rollout path returned by the thread APIs.
What is the expected behavior?
### Expected behavior
After the first real user turn completes on a non-ephemeral shared thread:
- rollout file should exist at the advertised path
- thread/read(includeTurns: true) should succeed
- sibling thread/resume should succeed
Actual behavior
The turn fully runs, but no rollout file is created.
Observed repro thread:
- thread id:
- 019d5fe8-3730-7dc0-b126-bd5bd37446bd
- advertised rollout path:
- /Users/.../.codex/sessions/2026/04/05/rollout-2026-04-05T18-09-07-019d5fe8-3730-7dc0-b126-
bd5bd37446bd.jsonl
After turn/completed:
- thread/read(includeTurns: false) succeeds
- thread/read(includeTurns: true) returns:
- thread 019d5fe8-3730-7dc0-b126-bd5bd37446bd is not materialized yet; includeTurns is unavailable
before first user message
- sibling thread/resume returns:
- no rollout found for thread id 019d5fe8-3730-7dc0-b126-bd5bd37446bd
- the rollout file does not exist on disk at the advertised path
Waiting a few more seconds does not change the outcome.
Additional information
### Notes
This seems to specifically affect shared-thread / multi-client websocket usage.
Lightweight thread state is visible across clients, but rollout-backed operations never become available
because the rollout is never materialized.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
What you're describing should work, so this does sound like a bug. Thanks for reporting it.
I asked codex to investigate. It wrote a small app server client that attempts to replicate the steps you've described above, but it wasn't able to duplicate the behavior you're seeing. It was able to theorize a potential cause, but it involves pretty obscure error cases that strike me as pretty implausible.
Perhaps you could ask codex to do something similar to what I did — to write a minimal test case that exercises the app server API via a web socket? If you're able to repro the problem in that way, perhaps you could then share the test case with me?
Alternatively, you could clone the codex code, build it from source, and ask codex to debug the issue on your machine directly.
thank you @etraut-openai
I packaged a minimal standalone websocket repro and ran it against a fresh local app-server on
codex-cli 0.117.0.Setup:
codex app-server --listen ws://127.0.0.1:9895WebSocketWhat the script does:
initializethread/startturn/startwith valid V2UserInput[]turn/completedOne repro run produced:
019d62ef-a95d-7742-952a-43ac59aa6733019d62ef-aa93-7ec0-b34e-b76b3dcb2213/Users/.../.codex/sessions/2026/04/06/rollout-2026-04-06T08-16-06-019d62ef-a95d-7742-952a-43ac59aa6733.jsonlThe turn completed successfully, but the rollout still did not exist on disk afterward:
rollout_exists: falseThe app-server logs also emitted repeated errors during the run:
```text
failed to record rollout items: failed to queue rollout items: channel closed
Here is the minimal standalone websocket repro script I used locally against codex-cli 0.117.0.
Thanks for the script. Unfortunately, I'm still not able to repro the problem — at least not with the latest main branch.
I took a quick look at this locally, and one thing that stood out is that the app-server terminal turn path seems different from the shutdown path.
From what I can tell,
TurnCompletenotifies clients, but does not appear to force rollout materialization/flush. The shutdown path does call rollout materialization/flush. That seems consistent with the issue showing up more clearly in long-lived shared websocket sessions, where shutdown may not happen soon after the turn completes.I tried a small local patch that materializes/flushes the rollout after terminal turn events in app-server event handling, and
cargo check -p codex-app-serverpasses locally. Not sure if this is the intended fix direction, but wanted to share the observation in case it helps.