[Bug]: Codex turns started by `codex queue` run in T3's app-server but never appear in the thread#23919
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Start a Codex thread in T3 and let its turn finish, so the provider session stays loaded.
- Within T3's idle window, queue a message for that thread from outside T3:
codex queue --thread <codex thread id> --message "Reply with the word QUEUED." - Wait about 10 seconds. Codex's queue watcher polls every 10 s and on thread-idle.
- Look at the thread in T3.
We found this through a plugin rather than a manual codex queue. The plugin does work asynchronously after the agent edits files. Under Codex, which has no asyncRewake, it reports results that arrive after the turn has ended by running codex queue --thread <id> --message <results>. The manual steps above use the same path.
Expected behavior
T3 shows the queue-triggered turn in the thread: the queued message, the agent's reply, and any tool calls. It's like how T3 shows Claude turns started by a background wake. Approvals requested during that turn reach the user.
Actual behavior
Codex runs the turn in T3's app-server process, but T3 never records it.
- The thread in T3 still shows one run, ending with "READY". The queued message and the "QUEUED" reply never appear, and the thread's
updatedAtstays at the end of the first run. - The model did receive and act on the queued message. With the plugin, the same thing happened: the model got the plugin's results and the user saw nothing.
What we think is happening:
- Codex's queue watcher starts the turn (
turn_trigger: "queue") in whichever app-server has the thread loaded. That's T3's process: openai/codexcodex-rs/ext/queue/src/service.rs. CodexAdapterV2.tshas no handler forthread/queue/changed.- In the
turn/startedhandler, a turn that is neither inactiveTurnsnor inpendingRootTurnsfalls through to the sub-agent bookkeeping (rememberSubagentTurnStarted, which parks it inpendingSubagentTurns). The turn is never projected as a run. References are to upstreammainat 51273020.
Impact
Minor bug or occasional failure
Version or commit
main @ 51273020
Environment
Linux (Ubuntu-based dev container), Codex provider, gpt-5.6-luna.
Logs or stack traces
| 1 | 03:24:46.250 turn/completed agentMessage "READY" (the T3 run) |
| 2 | 03:25:03 codex queue ... exits 0: "Queued message ... for thread ..." |
| 3 | 03:25:11.704 thread/queue/changed |
| 4 | 03:25:11.725 turn/started (native turn id unknown to T3) |
| 5 | 03:25:11.746 item/completed userMessage "Reply with the word QUEUED." |
| 6 | 03:25:12.765 item/completed agentMessage "QUEUED" |
| 7 | 03:25:12.805 hook/started / hook/completed (Stop) |
| 8 | 03:25:12.973 turn/completed |
Screenshots, recordings, or supporting files
No response
Workaround
None in T3. Plugin authors can avoid codex queue by returning results synchronously from a blocking Stop hook ({"decision":"block","reason":...}), which continues the same turn. That doesn't help other external callers of codex queue.