Desktop: codex_app__* dynamic tool dispatch starves while an unrelated remote SSH host is mid-reconnect (calls hang forever, no timeout)

Open 💬 1 comment Opened Jul 20, 2026 by michaelort33

What version of Codex is running?

Desktop 26.715.31925 (reproduced) → 26.715.52143 (current); codex-cli 0.144.4; remote app-server 0.144.3

What platform is your computer?

macOS (Darwin 25.5.0, arm64)

What issue are you seeing?

codex_app__* dynamic app tools invoked from a Code Mode exec cell (e.g. tools.codex_app__set_thread_title) hang forever — the promises never settle, no error, no timeout — whenever the desktop's remote SSH app-server connection to an unrelated host is mid-reconnect. The target of the calls is the local app-server; the remote host is not involved in the operation at all.

The remote host in my setup is an Azure VM (discovered from ~/.ssh/config) that auto-shuts down overnight, so every scheduled automation that runs at night and tries to rename threads fails with an indefinite hang.

Evidence from desktop main-process logs

Working renames always produce [AppServerConnection] response_routed … method=thread/name/set (10–40 ms each). Two correlated observations:

1. Dispatch freezes exactly for the lifetime of an in-flight SSH connect attempt:

| Time (UTC) | Event |
|---|---|
| 22:40:21 | app_server_connection.reconnect_started for the SSH host (attempt 23) |
| 22:40:42 | Automation submits 9 concurrent codex_app__set_thread_title calls — cell freezes |
| 22:46:31 | transport_connect_failed ("SSH: codex path probe timed out after 60000ms" — note this probe itself ran ~6 min, not 60 s) |
| 22:46:35–39 | All 9 renames flush instantly, ~500 ms apart, durationMs 10–40 each; cell completes ok:9 fail:0 |

2. When the reconnect wedges permanently, dispatch starves permanently:

The host went unreachable overnight; the reconnect loop went log-silent for ~7.5 h (no state transition from ~00:14 to 07:41 UTC). An automation run at 04:26 UTC issued 11 codex_app__set_thread_title calls: zero thread/name/set requests ever appeared in AppServerConnection logs, none persisted to state_5.sqlite, and the calls never rejected. During the same window, exec_command cells and renderer-originated requests (thread/turns/list) worked normally — only the codex_app__* dynamic-tool dispatch path was starved. When the host came back at 07:41:47 (nextState=connected), a subsequent thread/name/set completed in 12 ms.

Not the cause: SQLite is healthy (WAL, integrity ok, no busy/locked), no crash reports, titles/lengths fine, thread ownership irrelevant.

Expected behavior

  • Dispatch of local app tools should not serialize behind an unrelated remote host's connection state machine.
  • A dynamic tool call should carry a dispatch-level deadline so callers get a structured timeout error instead of a promise that never settles.
  • The "codex path probe timed out after 60000ms" timeout should actually fire at ~60 s; observed probes ran 6 min to 7.5 h.

Possibly related: #28080 (thread tools lose handlers mid-session), #31366 (older threads not exposing codex_app tools).

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗