# \[Bug\]: Codex turns started by \`codex queue\` run in T3's app-server but never appear in the thread · Issue \#23919 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/issues/23919)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: backlog

Priority: 0

## Description

[Discussion and activity](https://git.cafe/pingdotgg/t3code/issues/23919)

---

### Before submitting

- [x] I searched existing issues and did not find a duplicate.
- [x] I included enough detail to reproduce or investigate the problem.

### Area

apps/server

### Steps to reproduce

1. Start a Codex thread in T3 and let its turn finish, so the provider session stays loaded.
2. 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."`
3. Wait about 10 seconds. Codex's queue watcher polls every 10 s and on thread-idle.
4. 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 `updatedAt` stays 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/codex `codex-rs/ext/queue/src/service.rs`.
- `CodexAdapterV2.ts` has no handler for `thread/queue/changed`.
- In the `turn/started` handler, a turn that is neither in `activeTurns` nor in `pendingRootTurns` falls through to the sub-agent bookkeeping (`rememberSubagentTurnStarted`, which parks it in `pendingSubagentTurns`). The turn is never projected as a run. References are to upstream `main` at 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

```shell
03:24:46.250  turn/completed            agentMessage "READY"   (the T3 run)
03:25:03      codex queue ... exits 0: "Queued message ... for thread ..."
03:25:11.704  thread/queue/changed
03:25:11.725  turn/started              (native turn id unknown to T3)
03:25:11.746  item/completed            userMessage "Reply with the word QUEUED."
03:25:12.765  item/completed            agentMessage "QUEUED"
03:25:12.805  hook/started / hook/completed (Stop)
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`.
