Desktop thread tools intermittently lose handlers (`No handler registered`) within an active session

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

What version of the Codex App are you using?

Codex Desktop 26.608.1337.0 on Windows.

Bundled / installed CLI observed during the investigation: codex-cli 0.128.0.

What platform is your computer?

Windows 11 x64.

What issue are you seeing?

During an active Codex Desktop session, official thread-management tools intermittently lose their registered handlers and start returning errors such as:

No handler registered for tool: read_thread
No handler registered for tool: set_thread_title
No handler registered for tool: set_thread_archived

This happens even though the same tools were available and working earlier in the same Desktop session.

In the affected workflow, these tools are used to manage UI-visible notification worker threads:

  • inspect whether a worker thread is idle or stuck (read_thread)
  • rename threads to reflect active / standby / retired state (set_thread_title)
  • archive retired worker threads (set_thread_archived)

When handlers disappear, the automation can still update durable route files, but it cannot reliably clean up or relabel the Desktop UI. This leaves stale/retired worker threads visible and makes the session state misleading.

What steps can reproduce the bug?

This is intermittent, but the observed sequence was:

  1. Use Codex Desktop on Windows with a project thread open.
  2. Use the official thread-management tools successfully earlier in the session, e.g. set_thread_title and set_thread_archived.
  3. Continue normal agent work involving background/heartbeat-related notification routing.
  4. Later in the same session, call read_thread for a known thread.
  5. Observe:
No handler registered for tool: read_thread
  1. Attempt to recover by using other thread-management tools.
  2. Observe:
No handler registered for tool: set_thread_title
No handler registered for tool: set_thread_archived

The tools are still exposed to the model/tool layer, but the Desktop-side handler is unavailable.

What is the expected behavior?

  • If Desktop exposes read_thread, set_thread_title, and set_thread_archived, their handlers should remain registered and callable for the active session.
  • If a plugin/app-server bridge is temporarily unavailable, Desktop should reinitialize it or return a structured recoverable error with a suggested recovery path.
  • Tool discovery should not advertise tools whose handlers are not currently registered.
  • Thread-management failures should not require restarting Codex Desktop or manual UI cleanup.

Additional information

This may be related to Desktop/app-server subscription or target-thread state issues, but it is not exactly the same symptom as the heartbeat target resume loop described in #19563.

It may also be related to UI-visible notification delivery/tool-call state problems reported separately in #28070, where thread delivery side effects and Desktop UI state can diverge.

Operational impact: workflows that depend on official thread tools for failover/cleanup can update backend files correctly, but cannot make the Desktop UI match reality when handlers disappear.

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 1 month ago

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

  • #27960

Powered by Codex Action

Hogna67 · 1 month ago

Additional observation from the same Windows Desktop session:

While testing a recovery path that should wake the current thread via a heartbeat automation, the automation tool handler also disappeared:

No handler registered for tool: automation_update

This happened after other thread-management tools had already returned similar errors (read_thread, set_thread_title, set_thread_archived).

Operationally, this blocks a safe repair workflow: when a notification worker thread appears stuck, the background watchdog can write a repair queue, but it cannot reliably create/update a heartbeat to wake the coordinating thread because automation_update itself may have no registered handler.

A raw automation.toml written to $CODEX_HOME/automations/<id>/automation.toml did not fire within a 75 second smoke-test window, so using the official automation tool seems necessary, but the handler was unavailable.

aemilcar · 17 days ago

I observed a related failure on macOS in Codex Desktop, with codex_app.read_thread_terminal specifically.

Environment:

  • Codex bundled CLI: codex-cli 0.142.3
  • Platform: macOS 26.5.1
  • Architecture: arm64
  • Surface: Codex Desktop app

Observed behavior:

  • The app tool codex_app.read_thread_terminal was exposed/callable to the agent.
  • When invoked, the agent loop blocked for approximately 9h 25m.
  • The call eventually returned:
No handler registered for tool: read_thread_terminal

This was not a long-running shell/test process. The local command the agent was trying to inspect had completed much earlier; the agent was suspended waiting on the app tool call.

Why this seems related:

  • The tool was visible to the model/tool layer, but the Desktop-side handler was unavailable.
  • The failure did not fail fast.
  • The UI made it hard to tell that the agent was blocked on an app tool dispatch rather than on terminal/test execution.

Expected behavior:

  • If a Desktop app tool is exposed, its handler should be registered and callable.
  • If the handler is unavailable, the call should fail fast with a recoverable error.
  • Long-running app tool calls should have a watchdog/timeout or visible blocked-on-tool state.
  • Tool-dispatch waits should be distinguishable from shell/process waits in diagnostics.

I am intentionally omitting session IDs, local paths, raw logs, and project details because this is a public issue.

johnsilvavlogs · 10 days ago

Additional macOS reproduction on the current latest Desktop build, including a recovery boundary that may help isolate the handler lifecycle.

Environment:

  • ChatGPT/Codex Desktop 26.707.31428, build 5059
  • bundled CLI codex-cli 0.144.0-alpha.4
  • global CLI codex-cli 0.144.1
  • macOS 26.5.2 (25F84), arm64

Observed in a long-running Desktop manager thread that had successfully used the official thread tools earlier:

  • The tools remained advertised to the model, but calls to list_projects, list_threads, create_thread, set_thread_title, and read_thread_terminal stopped returning.
  • Repeated bounded waits of 60-150 seconds produced neither a result nor a structured error.
  • A timed-out create_thread call did not create a child in this reproduction; I checked both current thread state and recent rollout/session records before retrying.
  • Normal model turns, shell commands, goal state, and GitHub connector tools continued working. The Desktop app-server remained alive, and a process sample showed the code-mode host idle/waiting rather than CPU-spinning.
  • state_5.sqlite passed PRAGMA integrity_check.

Recovery boundary:

  • I did not restart or modify the app/database because active threads needed preservation.
  • On the next fresh user turn in the same thread, list_projects and list_threads immediately returned successfully again.
  • The manager title/pin handlers also worked after that turn boundary.

This looks like an advertised-handler/bridge state that can be lost within a turn and rehydrated by a fresh user turn, rather than a permanently dead app-server. A fail-fast watchdog plus explicit handler re-registration at turn/resume boundaries would avoid multi-minute/indefinite stalls. create_thread should also return an explicit delivered/not-delivered/uncertain operation state so retries remain safe.

Separate observation, not claimed as causal: this profile's logs_2.sqlite is about 3.9 GB with a large freelist; that lifecycle is already covered by #30431.

ttrias · 10 days ago

Cross-reference: #32294 appears to be the automation-specific form of this handler-registration problem.

In #32294, codex_app.automation_update remained exposed in the tool catalog while calls failed with No handler registered for tool: codex_app.automation_update. The same thread later succeeded without changing its persisted automation TOML. There is also a source correlation: the failing turn lacked a recorded client_id, while the later successful Desktop turn had one.

The shared failure mode is tool discovery and Desktop handler availability diverging. The automation variant can strand persistent scheduled state because the supported pause/update/delete path becomes unavailable.

jtcchan · 4 days ago

One additional source-level correlation for this handler-loss symptom: the packaged Desktop renderer's dynamic-tool dispatcher awaits the selected handler with no outer timeout, and only sends the mcp-response after that promise settles. A lost/stale/non-settling handler dependency can therefore leave a visible tool call pending indefinitely rather than returning No handler registered or another retryable error.

A later retry of the previously blocked tasks succeeded, consistent with a transient registration/renderer-activation boundary. The fuller timing, focus-state, and fix recommendations are documented in https://github.com/openai/codex/issues/31584#issuecomment-4989492449.