Repository navigation
Desktop thread tools intermittently lose handlers (No handler registered) within an active session #28080
Description
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:
- Use Codex Desktop on Windows with a project thread open.
- Use the official thread-management tools successfully earlier in the session, e.g.
set_thread_titleandset_thread_archived. - Continue normal agent work involving background/heartbeat-related notification routing.
- Later in the same session, call
read_threadfor a known thread. - Observe:
No handler registered for tool: read_thread
- Attempt to recover by using other thread-management tools.
- 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, andset_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.
Activity
github-actions commentedon Jun 13, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Hogna67 commentedon Jun 13, 2026
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:
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_updateitself may have no registered handler.A raw
automation.tomlwritten to$CODEX_HOME/automations/<id>/automation.tomldid not fire within a 75 second smoke-test window, so using the official automation tool seems necessary, but the handler was unavailable.aemilcar commentedon Jul 3, 2026
I observed a related failure on macOS in Codex Desktop, with
codex_app.read_thread_terminalspecifically.Environment:
codex-cli 0.142.3Observed behavior:
codex_app.read_thread_terminalwas exposed/callable to the agent.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:
Expected behavior:
I am intentionally omitting session IDs, local paths, raw logs, and project details because this is a public issue.
johnsilvavlogs commentedon Jul 10, 2026
Additional macOS reproduction on the current latest Desktop build, including a recovery boundary that may help isolate the handler lifecycle.
Environment:
26.707.31428, build5059codex-cli 0.144.0-alpha.4codex-cli 0.144.126.5.2(25F84), arm64Observed in a long-running Desktop manager thread that had successfully used the official thread tools earlier:
list_projects,list_threads,create_thread,set_thread_title, andread_thread_terminalstopped returning.create_threadcall did not create a child in this reproduction; I checked both current thread state and recent rollout/session records before retrying.state_5.sqlitepassedPRAGMA integrity_check.Recovery boundary:
list_projectsandlist_threadsimmediately returned successfully again.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_threadshould 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.sqliteis about 3.9 GB with a large freelist; that lifecycle is already covered by #30431.ttrias commentedon Jul 11, 2026
Cross-reference: #32294 appears to be the automation-specific form of this handler-registration problem.
In #32294,
codex_app.automation_updateremained exposed in the tool catalog while calls failed withNo 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 recordedclient_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 commentedon Jul 16, 2026
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-responseafter that promise settles. A lost/stale/non-settling handler dependency can therefore leave a visible tool call pending indefinitely rather than returningNo handler registeredor 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 #31584 (comment).
quiezent commentedon Jul 21, 2026
Additional Windows reproduction on Desktop 26.715.7063
I reproduced this on 2026-07-21 with a substantially newer Windows Desktop build.
Environment
26.715.7063.0codex-cli 0.145.0-alpha.18Observed
The live deferred tool registry advertised all 15
codex_app__*tools, but calls returned:Normal shell calls, GitHub/connector tools, and the separate collaboration/subagent route continued to work, so this was not a general model turn or app-server outage. A separately spawned diagnostic agent using the same Desktop bridge reproduced the read-only handler failures.
Update/restart boundary
26.715.4045.0to26.715.7063.0, and the new main process was independently verified.Thus, for this reproduction, a verified application update plus full process restart did not rehydrate the existing thread's Desktop handlers. This is consistent with a persisted per-thread/bridge-state problem, although I have not yet run the stronger control of creating a brand-new user-visible local task under the new build.
Side-effect reconciliation
I made exactly one
send_message_to_threadcall to a user-authorized idle test thread and did not retry it. It returned the handler error. I then checked the target rollout directly: its line count and last-write timestamp were unchanged, and the diagnostic text was absent. Therefore this particular failure did not deliver, unlike the uncertain-delivery behavior reported in #29886.This reinforces the need for explicit
delivered/not_delivered/unknownsemantics and for callers not to retry side-effecting thread tools blindly.Local paths, account data, and thread IDs are intentionally omitted.
DKWien commentedon Jul 26, 2026
Confirming quiezent’s reproduction on an even newer Windows build: I can reproduce the same handler-registration failure on Codex Desktop 26.721.4979.0.
The affected tools were exposed as available, but invoking them returned:
No handler registered for tool: list_projectsNo handler registered for tool: list_threadsNo handler registered for tool: fork_threadThe failure occurred while Codex was trying to inspect the current project/thread state and create a successor task in the same project.
I fully restarted Codex Desktop and repeated the calls, but all three tools continued to return the same errors. In this occurrence, the problem therefore persisted across an application restart.
Impact: automatic workflow continuation and successor-task reconciliation were blocked, requiring manual intervention. No repository data was lost.
I have also submitted this through
/feedback.Feedback reference:
019f9f51-f7f2-7b91-8f3e-ed7145bcc0e1quiezent commentedon Jul 27, 2026
Controlled Windows reproduction: handler loss, false-negative delivery, and fresh-turn recovery
Reproduced on 2026-07-27 in a newly created local Desktop task, not a legacy task.
Environment
26.721.4979.0codex-cli 0.146.0-alpha.3.1Baseline
The new coordinator task had already completed a four-task, six-pair messaging mesh.
send_message_to_thread,read_thread, andwait_threadshad all worked earlier in the same task/session.Exact sequence (UTC)
14:26:56.660—send_message_to_threadcalled once for a local manager task.14:26:57.218— caller received:Target rollout nevertheless recorded the exact matching
codex_delegation(including the expected source task and unique prompt token) at14:27:00.959. The send therefore delivered despite the handler error.In a later turn, three sends succeeded at
14:31:48,14:31:57, and14:32:07.Immediately afterward in that same turn,
wait_threadsfailed twice at14:32:12.348and14:32:30.734with:The second failure followed fresh tool discovery. This was tool-specific loss:
send_message_to_threadhad just succeeded whilewait_threadshad no handler.14:52:32.804— another singlesend_message_to_threadcall was made to a different local manager task.14:52:33.442— caller again receivedNo handler registered for tool: send_message_to_thread.Target rollout recorded the exact matching delegation at
14:52:33.827, only 385 ms later. This is a second confirmed false-negative delivery.A fresh diagnostic user turn at
14:59(without restarting Desktop) successfully called bothsend_message_to_threadandread_thread; the return token arrived and the read succeeded.One early failing turn lacked a recorded
client_id, but the later false-negative send and thewait_threadsfailures occurred in turns that did haveclient_idvalues. Missingclient_idmay correlate with some occurrences, but it is not necessary for this failure.What this narrows down
This appears to combine #28080's transient advertised-handler loss with #29886's post-delivery acknowledgement failure:
send_message_to_thread,No handler registeredis not a reliablenot_deliveredresult. The side effect may already have occurred.Safety impact
Blindly retrying a side-effecting task call after this error can duplicate work. Until the API distinguishes delivery from acknowledgement, the safest caller behavior is:
UNKNOWN, not failed;read_threadto reconcile the exact source ID and nonce in the target;read_threadis also unavailable, stop and surface uncertainty.It would help if the tool returned explicit
delivered,not_delivered,unknown, ordelivered_but_ack_failedsemantics plus a stable receipt/message ID, and if Desktop re-registered advertised handlers at every turn/resume boundary.DKWien commentedon Jul 28, 2026
Additional Windows reproduction from a scheduled watcher
Observed on 2026-07-28 with Codex Desktop 26.721.4979.0 on Windows 11 x64.
This reproduction is specifically from a recurring local-project watcher whose first operation is a bounded thread snapshot:
list_threads(limit=20)was called once per scheduled invocation.No handler registeredfor the same Desktop thread-tool family.UNCLEARand fail closed, so it could not safely reconcile or dispatch the already-reserved successor.This suggests the failure is not primarily caused by a large visible-thread set. Archiving reduced the enumeration workload but did not eliminate the handler/bridge failure.
Operational impact: a safe scheduler cannot distinguish “no active worker” from “thread snapshot unavailable”, so autonomous continuation stalls even though local repository state and workflow reservations are valid. Retrying side-effecting calls remains unsafe because delivery/acknowledgement can be ambiguous; explicit
delivered/not_delivered/unknownsemantics and fail-fast availability reporting would help.I am omitting local paths, task IDs, account data, and raw session logs.
hirsrsk commentedon Aug 2, 2026
Additional Windows reproduction on Desktop 26.727.6591.0
I observed the same advertised-tool/handler divergence on 2026-08-03 in a long-lived local Codex Desktop task.
Environment
26.727.6591.00.146.0-alpha.9.2Baseline
The same task had successfully called the app-native thread-management tools multiple times earlier in the same Desktop session, including
list_threads,read_thread, andwait_threads.Observed failure
Later, without a user-initiated app restart, update, or settings change:
read_threadreturned:An immediate
list_threadscall returned:The runtime tool catalog still contained the canonical
codex_app__read_thread,codex_app__list_threads, and related thread-tool definitions. Discovery/advertisement therefore remained present while the Desktop-side handlers were unavailable.Unrelated tool families continued to work normally in the same task, including web search, the GitHub connector, and a separate MCP file tool. Normal model turns also continued. This was not a general tool-runtime or app-server outage.
No thread mutation or retry of a side-effecting thread tool was attempted after the failure.
This is consistent with the task-scoped handler-registration divergence described here and in #36013, and confirms that the failure family persists on a newer Windows Desktop build and bundled CLI.
Expected behavior
If a thread-management tool remains advertised to the active task, its handler should remain registered and callable. If registration is lost, Desktop should either rehydrate the handler atomically or omit the tool and return a structured, recoverable availability error.
All task identifiers, task titles, project/customer names, local paths, account identifiers, prompt contents, and raw logs are intentionally omitted from this public report.
quiezent commentedon Aug 3, 2026
Scheduler-impact reproduction on Windows Desktop 26.727.6591.0
Observed across the 2026-08-03 / 2026-08-04 boundary in Codex Desktop on Windows x64.
Environment
26.727.6591.00.146.0-alpha.9.2Operational sequence
No handler registered for tool: send_message_to_threadNo handler registered for tool: read_threadNo handler registered for tool: list_threadsNo handler registered for tool: automation_updateNo handler registered for tool: navigate_to_codex_pageread_threadwas also unavailable, delivery could not be reconciled safely. No blind message retry was made.automation_updatewas unavailable, the coordinator's persisted automation could not be repaired or rearmed through the supported Desktop path. The existing automation remains stranded in its previous state.Fallback boundary
Using the matching CLI with
codex exec resume <session-id> <prompt>successfully appended governance-only messages to each task individually. However, an exec-resumed task cannot repair the automation: attempting the dynamic app tool reports that dynamic tool calls are unsupported in exec mode. Directly editing automation TOML was intentionally avoided.This adds a concrete operational impact to #28080 and the automation-specific report in #32294: transient handler loss can suppress independent scheduled workers and then remove the only supported recovery/rearm path.
Expected recovery semantics:
delivered,not_delivered,unknown, ordelivered_but_ack_failedstatus plus a stable receipt for message sends;No task IDs, local project paths, account identifiers, portfolio data, or raw prompts are included here. No external-system mutation occurred during the reproduction.
hirsrsk commentedon Aug 4, 2026
Interim caller-side mitigation pattern (not a product fix)
The recent scheduler-impact reproduction suggests a useful interim operating pattern for coordinators and automations while the Desktop handler-lifecycle bug remains unresolved. This is intended to limit duplicate work, indefinite stalls, and unrelated-work suppression; it does not repair the underlying Desktop bridge.
UNKNOWN. Send once with a unique operation key or nonce. Reconcile that exact marker throughread_threadbefore retrying. If the read path is also unavailable, stop and surface uncertainty rather than retrying blindly.codex exec resume <session-id> <prompt>may append a prompt to an existing task, but the resumed CLI turn cannot invoke Desktop-hosted dynamic app tools or repair/manage automations. It is therefore not a complete fallback.Product-side behavior that would make this reliable:
delivered,not_delivered,unknown, ordelivered_but_ack_failedstatus plus a stable receipt for side-effecting calls;This pattern is deliberately conservative about ambiguous delivery while avoiding the current failure mode where one unresolved call can block an entire coordinator. No task identifiers, local paths, account data, project/customer names, or raw prompts are included.
fibo-blip commentedon Aug 4, 2026
Remote Control connection correlation
Cross-reference: #36673 reports the same advertised-thread-tool / missing-handler failure while a Desktop task coordinates an existing remote task.
A Windows Desktop occurrence provides a stronger Remote Control correlation.
Recorded thread-tool timeline
Times below are Europe/Lisbon (WEST, UTC+1):
read_thread.read_threadattempts returned:Disconnectaction shown for that active Remote Control connection was subsequently invoked. This was not removal or deauthorization of the device; it appears to disconnect the active Remote Control session/connection.read_threadprobe was made immediately whenDisconnectwas invoked.read_threadfor two known local task IDs.The measured recovery window is therefore:
There was also an earlier observed occurrence with the same sequence: an active Remote Control connection remained established while work resumed on the primary Desktop, local task reads were unavailable, and task access returned after
Disconnectwas invoked for that Remote Control connection.This is a repeated correlation between active Remote Control connection state and local Desktop thread-handler availability. The samples do not establish the exact re-registration moment or whether invoking
Disconnectis the direct cause, because there was no continuous probe between disconnect and recovery. However, Remote Control host/controller routing should be included explicitly in diagnosis rather than treating this only as a generic per-turn handler-loss issue.Useful diagnostics would include:
Disconnectis invoked;quiezent commentedon Aug 4, 2026
Android Remote reproduction with confirmed non-delivery
A later controlled reproduction on 2026-08-04 narrows the Remote source and delivery outcome.
This occurred while ChatGPT Android Remote controlled an existing local Desktop Scheduler task. The task was not created from mobile.
Sanitized UTC timeline:
14:25:33— in an earlier Android-controlled turn, advertisedautomation_updatereturned:No handler registered for tool: automation_update14:30:38— a new Android Remote user turn reached the existing local Scheduler task.14:30:51— tool lookup exposedsend_message_to_thread.14:31:12— exactly one send was attempted to worker A.No handler registered for tool: send_message_to_threadDelivery was reconciled afterward against the exact worker rollout records. The send's unique prompt marker was absent from worker A's rollout at the audit cutoff. Thus this particular handler error represented true non-delivery, rather than the delivered-but-acknowledgement-failed behavior reported in #29886.
Environment:
26.727.6591.00.146.0-alpha.9.2This adds an Android Remote control-path boundary to the scheduled-coordinator reproduction already reported here:
The important safety conclusion is that the same caller-visible handler error has now been observed with both outcomes:
Accordingly, callers cannot safely retry or mark failure from this error alone. Side-effecting thread tools need a stable operation/message ID and an explicit result such as
delivered,not_delivered,unknown, ordelivered_but_ack_failed.Handler registration should also be revalidated atomically at Android Remote turn, task-resume, and scheduled-automation boundaries, and one target's unresolved result should not suppress unrelated targets.
Related Android-specific report: #32553. Automation-specific form: #32294. Scheduled-run overlap: #35030.
No task IDs, portfolio information, raw prompts, local paths, or account identifiers are included.
fibo-blip commentedon Aug 4, 2026
Controlled before/after
DisconnectreproductionA new A/B check on 2026-08-05 narrows the recovery boundary reported above.
Codex Desktop remained running throughout; there was no application restart.
Times below are Europe/Lisbon (WEST, UTC+1):
00:16:22.359—read_threadreturnedNo handler registered for tool: read_thread.wait_threadsalso returnedNo handler registered for tool: wait_threads.00:16:48.318—read_threadsucceeded.00:16:55.281—wait_threadssucceeded.The observed handler transition occurred within 26 seconds between the failed and successful
read_threadprobes, without an app restart or changes to the task/session data.This is stronger A/B evidence for the same boundary: an active Remote Control connection coincided with unavailable local Desktop thread handlers, and disconnecting that current connection was immediately followed by successful handler dispatch. It does not by itself prove the internal root cause, but it strongly points to Remote Control connection lifecycle or handler routing rather than rollout size or stored-session corruption.
ginishuh commentedon Aug 5, 2026
Controlled cross-surface resume reproduction: an existing coordinator thread remains poisoned across Mobile, Desktop, and CLI
I reproduced a stronger persistence boundary on 2026-08-05. This was an existing long-running project coordinator thread that had previously depended on the official Desktop thread tools.
Environment
codex-cli 0.146.0Reproduction timeline
Resume the existing coordinator thread from ChatGPT mobile remote.
The model still receives the official
codex_app__*thread-tool declarations.Calls fail with missing-handler errors, including:
A failed
create_threadattempt was rendered in Windows Desktop as a successful-looking "chat created" tool card, while the persisted assistant/tool result immediately below still containedNo handler registered for tool: create_thread. Because reconciliation tools were also unavailable, the caller could not safely determine whether the mutation happened and could not safely retry.Fully quit and restart Codex Desktop, then resume the same thread in Desktop. Read-only calls still fail:
Quit Desktop and resume the same persisted thread from WSL Codex CLI. The same calls fail instead with:
Open Desktop while the CLI-owned resume is still active. Calls retain the CLI-side
dynamic tool request failedresult.Exit the CLI completely, resume the thread again from Windows Desktop, and start a fresh user turn.
The errors switch back to the Desktop-specific missing-handler form:
Repeat the Desktop resume and read-only calls. The handler does not recover.
This distinguishes surface switching from recovery: the error mode follows the active surface, but the existing thread never rehydrates a working Desktop task-tool binding.
Operational impact
The affected coordinator thread can continue ordinary model turns and shell/GitHub work, but it can no longer safely:
The underlying existing tasks are not necessarily lost and can still be opened manually in the UI. The broken part is cross-thread coordination from the resumed coordinator. The practical recovery is to create a brand-new Windows Desktop coordinator task and manually transfer context, which defeats persistent-thread resume.
Expected behavior
On every
thread/resumeor remote/CLI/Desktop surface transition:delivered,not_delivered, orunknownsemantics for mutating thread tools so callers never retry blindly.Likely related boundaries
list_threadsadvertised but returns “No handler registered for tool” #36965 reportslist_threadsbeing advertised without a handler on current Windows Desktop.This reproduction appears to connect those symptoms: dynamic tool definitions persist with the thread, executable handlers remain surface/client-specific, and resume does not reliably reconcile the two.
No private prompts, project paths, credentials, or thread IDs are included.
rayhlw commentedon Aug 5, 2026
macOS + iPhone Remote Control reproduction: surface switch changes route and drops
wait_threadshandlerI can reproduce a surface-switch-specific variant on the current macOS build.
Environment
26.730.61639(build6234)codex-cli 0.147.0-alpha.1.227.0(26A5388g)Minimal sequence
list_threadsreports both threads on aremote-control:*host route.slingshot:*, while thread listings may still resolve the same identities throughremote-control:*.codex_app.wait_threadsonce for the known worker, including an immediatetimeoutMs: 0snapshot.send_message_to_threadcall to an existing visible diagnostic worker may return:However, the target thread's update timestamp changes, it runs to completion, and its worker-to-coordinator
send_message_to_threadmessage is delivered successfully. This is a confirmed delivered-side-effect / lost-ack case.8. Switching control back to the computer changes the observed route again without restarting either app. The worker itself never loses state.
What this narrows down
remote-control:*andslingshot:*routing during the failure window.wait_threadscan be unavailable while ordinary visible-task execution and worker-to-coordinator delivery still work.Expected behavior
delivered,not_delivered,unknown, ordelivered_but_ack_failedstatus plus a stable operation/message ID.wait_threadsresolve the live thread identity independently of whether the coordinator was most recently resumed from mobile or desktop.Operational workaround validated locally
Use a single idempotency key per worker turn; send exactly one native completion/material-blocker message to the coordinator; never retry on an acknowledgement error; treat
wait_threadsas optional monitoring and independently verify worker results. This keeps visible tasks usable across phone/computer switches but does not fix the underlying handler-registration bug.No project data or full session transcript is included here. I can provide a narrowly sanitized log window or feedback session ID if a maintainer requests it.
rayhlw commentedon Aug 5, 2026
Follow-up: the same surface switch can also change the worker model and reasoning effort
The same macOS/iPhone reproduction exposed a second route-bound state leak in one existing visible worker thread.
Local rollout
turn_contextrecords show this exact sequence:gpt-5.6-luna/xhighand remained on that pair across its normal turns.slingshot:*route started the worker's next turn asgpt-5.6-sol/medium.modelandthinking, which the tool contract says should keep the target thread's current settings.remote-control:*route, another continuation to the same worker, also without model/thinking overrides, started asgpt-5.6-luna/xhighagain.This indicates that control-surface route drift can affect not only handler registration and acknowledgements but also model/effort continuity for an existing task. The target thread identity and worktree did not change.
Expected behavior: omitting model/thinking on
send_message_to_threadshould preserve the target thread's bound settings regardless of whether the coordinator is currently routed through mobile or desktop. If the system intentionally applies a caller-side override, the API should expose that resolved routing before execution rather than silently changing the worker.Current safety workaround: coordinators must explicitly repeat the worker's model and effort on every continuation/correction. This avoids silent route-model drift but should not be necessary under the documented preservation behavior.
quiezent commentedon Aug 6, 2026
Additional Windows Desktop reproduction after a full process-tree restart and Store update (2026-08-06):
Environment
26.727.6591.0to26.730.8199.026.730.61639codex-cli 0.147.0-alpha.1.2Restart/update result
The old Desktop process tree was fully terminated and the signed Store package relaunched. The update completed successfully and a fresh app-server started. The defect persisted.
After restart, the deferred tool catalog continued to advertise full schemas for:
read_threadlist_threadssend_message_to_threadnavigate_to_codex_pageautomation_updateBut invocation immediately returned:
No handler registered for tool: <name>This reproduced in two existing Desktop threads. In the scheduler/coordinator thread, three independent manager sends each failed before recipient lookup; controlled reconciliation confirmed 0/3 native deliveries. Desktop logs explicitly showed
thread_toolsenabled after startup, so the observable failure is a divergence between the advertised dynamic-tool catalog and the live client handler registry.There was no positive Remote Control subscriber evidence in the local logs: remote host/control inventory remained zero during the reproduction.
Limited workaround and boundary
A current user-local CLI binary could resume each recipient session. Three bounded A2 continuations completed with matching acknowledgements, confirming the recipient sessions themselves were healthy. However this is not a product fix:
codex exec resumecannot service Desktop dynamic tools and reportsdynamic tool calls are not supported in exec mode.automation_updateor native inter-thread messaging generally.Get-Command codexresolved the packagedProgram Files\WindowsApps\...\codex.exe, which failed withAccess is denied; only the current user-local hashed CLI was executable.No release/restart recovery was observed on
26.730.8199.0. This remains consistent with a handler-registration/lifecycle defect rather than a recipient authorization or prompt problem.quiezent commentedon Aug 7, 2026
Scheduler dead-end confirmed on Windows Desktop 26.730.8199.0 (2026-08-07)
A scheduled-task coordinator reproduced the combined failure mode after the full restart/update described above.
read_thread,send_message_to_thread, andautomation_updateremained advertised but returnedNo handler registered.codex-cli 0.147.0-alpha.1.2.and the task received only:
This establishes a complete recovery dead-end:
Operational consequence in this reproduction: the persisted heartbeat retained a stale recurrence, and a time-sensitive next wake could not be armed despite the target thread and normal CLI execution remaining healthy. No duplicate automation was created and no messages were sent.
A useful product-level recovery would be either (a) deterministic handler re-registration at local/remote/CLI-resume boundaries, or (b) a supported app-server/CLI automation management command that returns explicit applied/not-applied state when the Desktop handler is unavailable.
ginishuh commentedon Aug 7, 2026
Post-update Android Remote matrix: no permanent poison, but tool-specific handler loss and false-negative mutations remain
I reran a controlled task-management matrix on 2026-08-07 after the latest available app update, from ChatGPT mobile Remote against the same existing coordinator that I previously reported in this comment.
This is a materially improved recovery boundary: the coordinator is no longer permanently unable to manage other tasks. However, advertised-handler divergence still occurs within one user turn, and some mutating calls can apply their side effect while returning
No handler registered.Environment and method
codex-cli 0.147.0codex_appfunctionsread_threador local session metadataResults
list_projectsNo handler registered for tool: list_projectslist_threadsNo handler registered for tool: list_threadscreate_threadread_threadsend_message_to_threadwait_threadsNo handler registered for tool: wait_threadsimmediately after the disposable task was createdset_thread_titleread_threadand session metadataset_thread_pinnedset_thread_archivedfork_threadNo handler registered for tool: fork_thread, but a fork was actually created with the completed source historyhandoff_threadget_handoff_statusread_thread_terminalopen_in_codexqueuedfor the mobile-controlled/hidden panelAdditional false-negative creation evidence from the same updated session
Immediately before the controlled matrix, three
create_threadcalls each returned:All three tasks were nevertheless created and visible in the mobile UI. The retries therefore produced three duplicates. They were later identified from session metadata and archived successfully. This confirms that the caller-visible handler error still cannot be treated as
not_deliveredforcreate_thread.What changed from the earlier reproduction
The previous affected coordinator remained poisoned across Mobile, Desktop, and CLI resumes and could not recover working task tools. After the update, the same practical workflow can now create, read, message, wait for, rename, pin, archive, fork, and hand off tasks. A fresh user turn also restored functions that had failed earlier.
The remaining defect is narrower but still unsafe:
list_projectsandlist_threadscan remain unavailable while other task tools work;wait_threadscan transition from working to missing-handler during the same turn;create_threadandfork_threadcan return a handler error after the side effect occurred;This still needs an explicit operation result such as
delivered,not_delivered,unknown, ordelivered_but_ack_failed, plus a stable operation/message ID. Advertised handlers should also be revalidated atomically at every mobile Remote turn/resume boundary and before dispatch.All disposable test tasks were archived, the temporary handoff worktree was removed after a clean-state check, and the repository checkout remained clean. No private task IDs, prompts, project names, or local paths are included here.
ginishuh commentedon Aug 7, 2026
Post-update mobile-created fresh root: all task-management tools missing
I ran this check on 2026-08-07 from a brand-new root task created directly in the ChatGPT mobile Remote UI immediately after the mobile app update. This was not a resume of an existing session. The operator subsequently confirmed that the thread under test itself—not merely its control surface—was created from mobile Remote.
Environment visible inside the remote task:
0.147.0source=vscode,originator=Codex Desktop, andthread_source=nullThe live tool registry exposed 0
codex_app__*tools. In particular, none of the 14 task-management functions from the earlier post-update matrix were available:list_projects,list_threads,create_thread,read_thread,wait_threads,send_message_to_thread,set_thread_title,set_thread_pinned,set_thread_archived,fork_thread,handoff_thread,get_handoff_status,read_thread_terminal, andopen_in_codex.I made one direct
open_in_codexinvocation attempt. It could not reach handler dispatch because the callable was absent from the registry (tools[toolName] is not a function). This is therefore not aNo handler registeredresult and does not establish a mutation false negative.The same thread was then continued across two subsequent fresh user turns. On both turns, the live registry still exposed 0 task-management tools. A direct
create_threadinvocation was attempted once in each of those explicitly requested turns; both attempts failed before handler dispatch withtools[toolName] is not a function. Exact-title readback from the local thread index returned no matching child, so neither attempt created the disposable task.Because no task-management readback tool was available, the remaining lifecycle matrix could not run safely. No task, fork, handoff, worktree, file, branch, commit, PR, or issue-state mutation was created; the original checkout remained clean.
This differs from the earlier post-update matrix, where all 14 functions were advertised but some handlers failed or returned false negatives. The fresh-root result is more directly related to #34526: it appears to be a stronger reduced-profile case, with the entire task-management surface omitted rather than only selected capabilities. It also means the fresh-root recovery boundary for #28080 cannot be validated from this task, because no handler can be invoked at all.
The persistence across fresh user turns makes a transient single-turn catalog failure less likely. The mismatch between the confirmed mobile creation path and the persisted
source=vscode/originator=Codex Desktop/ nullthread_sourcemetadata may be useful for locating the capability-profile routing boundary.Expected behavior: a mobile-created fresh Remote root should receive the same supported task-management profile as an equivalent full-profile task, or the product should explicitly disclose and diagnose the reduced profile.
copelandtucker0c5pg7p-droid commentedon Aug 9, 2026
Additional sanitized reproduction and recovery evidence from Windows 11 x64:
26.803.5235.00.147.0-alpha.6.5list_projectsandlist_threadsNo handler registered for tool: <tool>whileread_threadandwait_threadsremained callable.A minimal runtime-only recovery was tested: restart only the existing
codex-code-mode-host.exechild process and allow the current app-server to spawn a replacement. Desktop and app-server were not restarted, and no state/cache/database files were modified.Initial post-restart checks:
list_projects/list_threadscalls both succeeded (about 70 ms);Correction after a longer idle interval: after several additional minutes, both list tools again returned
No handler registeredin about 0.7 s while the replacement host process was still alive. Restarting only the code-mode host is therefore a temporary recovery, not a durable fix.This remains consistent with a stale code-mode-host / Desktop dynamic-handler bridge lifecycle rather than missing tool schemas or damaged thread state. A supported auto-reinitialize/retry path when the host-side handler bridge becomes stale would avoid requiring process restarts.