Remote SSH: `codex_app.wait_threads` has no registered handler while list/read/send remain healthy
What issue are you seeing?
In a Codex Desktop workflow using a Remote SSH host, codex_app.wait_threads is exposed to the coordinator but consistently fails immediately with:
No handler registered for tool: codex_app.wait_threads
Other task-control operations remain healthy in the same session:
list_threads: succeedsread_thread: succeedssend_message_to_thread: succeeds on real task dispatches- underlying tasks continue executing normally
wait_threads: fails with the missing-handler error
This materially impacts unattended coordinator/subagent workflows because the coordinator can dispatch and inspect work but cannot use the advertised wait primitive.
Environment
Remote host:
- Ubuntu 24.04 LTS
- x86_64
- Remote SSH through Codex/ChatGPT Desktop
Codex:
- CLI:
codex-cli 0.149.0 - remote app-server:
0.149.0 - npm installation
- npm
11.12.1 - ChatGPT authentication
- OpenAI provider / Responses API
Desktop controller:
- Windows Codex/ChatGPT Desktop
- updated to the latest version offered by the application
- fully restarted before the final reproduction
codex doctor after update/restart reported:
- app-server running
- websocket connected
- provider endpoints reachable
- state databases healthy / integrity OK
- configuration/auth healthy
- 0 failures
Clean reproduction
- Update the Remote SSH host's Codex CLI to
0.149.0. - Verify
codex --versionreportscodex-cli 0.149.0. - Fully restart the Windows desktop controller.
- Verify with
codex doctorthat the remote app-server is also0.149.0. - Ensure no second desktop controller is connected to the remote environment.
- Verify only one remote-host identity is visible.
- Use existing real tasks rather than synthetic work.
- Call task listing and reading: both succeed.
- Call
wait_threadsfor an existing healthy task. - Observe:
No handler registered for tool: codex_app.wait_threads
- Use the next naturally required
send_message_to_threaddispatch; it succeeds.
The target task remains healthy and readable, so this does not appear to be a crashed-task failure.
Expected behavior
If wait_threads is exposed as an available task-control tool, its handler should be registered and callable for the active session.
If the handler cannot be registered, tool discovery should omit the tool or return a structured recoverable availability error rather than exposing a callable-looking tool that deterministically returns No handler registered.
Actual behavior
wait_threads is exposed but fails immediately because no handler is registered, while list/read/send operations continue working against the same task environment.
Prior behavior
The same failure was previously observed on CLI/app-server 0.147.0.
On that version, send_message_to_thread could also intermittently time out while task listing/reading and the underlying tasks remained healthy. Restarting the desktop controller temporarily restored task control on one occasion, but the failure later returned during extended unattended execution.
After updating the CLI, remote app-server, and desktop controller, message dispatch is currently healthy on 0.149.0, but the wait_threads missing-handler failure remains reproducible.
Controller / host cleanup performed
A second desktop application had previously been open, so that was explicitly eliminated as a variable before the final reproduction:
- second desktop application fully quit
- Windows remained the sole desktop controller
- one remote-host identity visible
wait_threadsstill failed identically
Impact
This prevents reliable unattended multi-task coordination. A coordinator can dispatch work and inspect task state but cannot use the normal wait primitive, requiring degraded-mode polling/reconciliation logic to avoid stalling otherwise healthy work.
Current workaround
The coordinator currently:
- attempts the wait operation once;
- uses list/read to inspect state;
- does not repeatedly retry the broken wait handler;
- continues using message dispatch where possible;
- safely reconstructs stateless work when necessary;
- continues unrelated work rather than treating the missing handler as a global stop.
Additional diagnostic observation
codex doctor reports a warning that a small number of rollout files are missing from the state DB, while the state and thread-history databases themselves report integrity OK. I do not know whether this is related, but am mentioning it because the observed failure concerns thread/task control.
No raw logs, task IDs, hostnames, usernames, repository names, project names, local paths, credentials, external-service names, or prompt contents are included in this report.
Related reports appear to include #28080 and #36013, but this reproduction is specifically wait_threads on a current 0.149.0 Remote SSH CLI/app-server with list/read/send remaining healthy.
1 Comment
Additional clean-reproduction evidence: progressive task-control degradation
After the initial report, the task-control bridge degraded further with the same sanitized, single-controller topology:
list_threadssucceeded initially;read_threadsucceeded initially;wait_threadsfailed immediately with:The next naturally required
send_message_to_threadthen hung for more than 60 seconds and was terminated without a returned result.A single follow-up state inspection also hung. A one-time replacement-task dispatch likewise hung. No further retries were performed.
Importantly, the underlying remote workload remained healthy throughout: local execution, tests, typechecks, and CI continued to complete successfully. No underlying worker/runtime crash was observed.
The observed progression was therefore approximately:
This suggests progressive degradation in the Desktop/task-control bridge rather than failure of the Remote SSH worker/runtime itself.
No task IDs, host IDs, hostnames, usernames, repository/project names, local paths, prompts, credentials, or external-service details are included here.