Codex app thread-management tools not exposed despite thread creation being available
Summary
In a Codex desktop session, the user asked the assistant to open another Codex thread and send an execution prompt there. The app context says thread-management tools should be available through tool search, including create_thread, send_message_to_thread, fork_thread, list_threads, and related tools.
However, repeated tool searches did not expose any of those tools.
What happened
The assistant searched for:
create_threadsend_message_to_threadfork_threadlist_threads read_thread set_thread_title- broader queries such as
create thread Codex thread title message
No real thread-management tools were returned.
Because the real thread tool was unavailable, the assistant incorrectly fell back to spawning a multi_agent worker. The user then had to stop the worker, because they wanted a real sidebar Codex thread, not a background subagent.
Expected behaviour
If the Codex app supports user-owned thread creation, the thread tools should be discoverable and callable when the user explicitly asks to create/open/fork/send work to another thread.
At minimum, if thread tools are unavailable in a session, the assistant should have a reliable way to know that and report it clearly, instead of only discovering this through failed tool search.
Actual behaviour
Thread-management tools were not exposed through tool search, even though the app instructions referenced them and the user reports having used this capability many times.
Impact
This creates a confusing and potentially harmful fallback path:
- the assistant cannot perform the requested thread workflow;
- the assistant may confuse background subagents with user-owned Codex threads;
- the user loses control over where long-running work is happening;
- the assistant may start work in the wrong execution surface.
Suggested fix
Ensure thread-management tools are exposed when the Codex desktop app supports them, especially:
create_threadsend_message_to_threadfork_threadlist_threadsread_threadset_thread_title
Alternatively, provide an explicit unavailable state so the assistant can say: “I cannot create a real Codex thread from this session.”
Search performed before filing
Searched existing openai/codex issues for:
thread create_thread send_message_to_thread tool_searchcreate thread tools unavailabletool_search missing toolsthread management toolsmulti_agent thread
No close match was found.
Session details
Date: 2026-06-26
Context: Codex desktop app
Observed available fallback: multi_agent_v1.spawn_agent, which is not equivalent to creating a user-owned Codex thread.
5 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Additional reproduction from Codex Desktop on macOS, observed 2026-06-28.
This is a narrower variant than the original full-missing-tools report: the thread-management surface was partially exposed, but
create_threadwas ranked outside the first discovery page even when the exact query includedcreate_thread.Environment observed from the local machine:
codex-cli 0.142.126.623.42026/ build4514Repro notes:
list_threads read_thread create_thread fork_thread send_message_to_thread set_thread_title set_thread_pinned set_thread_archived handoff_thread Codex thread management, withlimit: 10.codex_apptool surface included thread/project tools such asread_thread,send_message_to_thread,set_thread_title,set_thread_pinned,set_thread_archived,list_projects,list_threads,fork_thread,handoff_thread, andget_handoff_status, but did not includecreate_thread.list_projectswas available and its description explicitly said to use the returnedprojectIdwithcreate_thread, making the exposed surface internally inconsistent.create_threadwas unavailable and used same-directoryfork_threadas a fallback for visible direct reports. That is a bad fallback because forked workers inherit completed manager history and are specifically discouraged for fresh direct-report creation.limit: 12) exposedcreate_threadas an additional result.Expected behavior:
create_thread,create_threadshould be surfaced ahead of adjacent utilities, especially below normal limits such as 8-10.list_projectswith documentation that referencescreate_threadwhile hidingcreate_threadleads agents to a false unavailable conclusion.Impact:
This causes Loop Engineering / manager workflows to create the wrong kind of visible worker (
fork_thread) or fall back to non-equivalent surfaces even though real thread creation is actually available. In high-pressure workflows, that can pollute worker context, create same-directory contention, and make the manager ledger inaccurate.This comment is intended as a concrete same-session reproduction to help separate “all thread tools missing” from “critical exact-match thread tool hidden by discovery ranking/limit.”
Adding another data point with a fairly complete before/after evidence set. Same symptom family: thread-management tools present in the session tool catalog but never callable.
Environment
26.707.91948, bundled enginecodex-cli 0.144.5(/Applications/ChatGPT.app/Contents/Resources/codex --version)Symptom
In affected sessions,
list_projects/create_thread/set_thread_title/list_threads/read_thread/fork_thread/handoff_thread/send_message_to_thread(plus pin/archive,automation_update,uninstall_plugin) all appear in the session's dynamic tool catalog withdeferLoading: true, but notool_searchis exposed in the callable surface, so the agent has no way to load them. Onlynavigate_to_codex_page,read_thread_terminal, andload_workspace_dependenciesare directly callable.Flag state that looks like the direct cause (from the bundled binary's
codex features liston 0.144.5):i.e. tools are still always deferred, but both loading paths (
tool_searchand the olderjs_replruntime) are gone. Deferred catalog + no loader = permanently unreachable tools.Timeline (from local session rollouts)
0.144.2(Jul 13–16): working — sessions received a JS runtime that could call the Desktop thread tools directly (list_projects → create_thread → set_thread_title → read/listall succeeded).0.144.2 → 0.144.4 → 0.144.5. After this, tool-runtime injection became intermittent: on the same version, same account, same evening, one session successfully calledcreate_threadand produced a GUI-visible child task, while other fresh sessions only receivedexec_commandwith the thread tools stuck in the deferred catalog.Ruled out locally (with counter-evidence)
config.toml/ hooks unchanged during the window; restarting the app puts the tools back in the catalog but still deferred and unloadable.Happy to provide sanitized session metadata comparisons (successful vs failed injection on the same build) if useful.
Additional controlled macOS reproduction on the current Codex Desktop build. This looks like a related but more specific failure mode: the cross-thread tools remain discoverable, but their model-facing handlers become unavailable or return false failures after a display-off/renderer visibility transition.
Environment
26.721.41059(released 2026-07-24), build58480.146.0-alpha.3.125.4.0 arm64caffeinateprocess heldPreventUserIdleSystemSleepandPreventDiskIdle, but notPreventUserIdleDisplaySleep. The Mac remained awake while its displays were allowed to turn off.Controlled sequence
list_threadsandread_threadboth worked in an existing long-lived task.Display is turned offat 2026-07-26 21:54:52 +0300. Full idle system sleep remained prevented.list_threadsreturnedNo handler registered for tool: list_threads;send_message_to_threadreturnedNo handler registered for tool: send_message_to_thread;thread/listand destinationturn/startoperations completing successfully with no error;read_threadsucceeded and proved that the supposedly failed message had actually been delivered;list_threadsprobe still returned the no-handler error.list_threadscontinued returningNo handler registered, while another Codex app tool,read_thread_terminal, reached its handler normally.list_threads,read_thread,send_message_to_thread, and message readback. The ChatGPT/Codex process PID and assertion age reset; the existingcaffeinateprocess and macOS power configuration did not.Relevant desktop-log evidence
Around the failed cross-thread message, logs recorded:
documentVisibilityState=hiddenpreviousResumeState=needs_resumeThe primary renderer successfully resumed the destination, became stream owner, started the turn, and returned success. At the same time, the hidden avatar-overlay renderer logged
Conversation state not foundandReceived turn/started for unknown conversation.This suggests a renderer/resume-state handler-registration or acknowledgement-routing problem. The underlying thread service was still operating. I cannot establish that display-off is the only trigger, but this experiment rules out full system sleep as necessary and shows that wake/unlock alone may not repair the state.
There is also a separate schema inconsistency on this build: deferred discovery advertises an optional
queryargument forlist_threads, while invocation rejects it as an unrecognized key. That persists even after restart restores the handlers.Impact
The false-negative mutation result is particularly risky: an agent may resend a message or repeat a thread-creation operation that already succeeded, causing duplicate work. Temporary subagents are not an equivalent fallback for durable user-owned Codex tasks.
I can provide sanitized timestamps and private diagnostic logs if useful.
Related reports: #29886 covers false-negative cross-thread message delivery, while #28080 covers intermittent thread-tool handler loss.
Follow-up with a separate controlled discovery failure on the same macOS installation. This is distinct from my earlier display-off/handler comment: here, the Codex task tools are omitted from
tool_searchresults before any invocation is possible.Environment
26.721.41059, released July 24, 2026codex-cli 0.146.0-alpha.3.1(/Applications/ChatGPT.app/Contents/Resources/codex --version)25.4.0 arm64Controlled comparison
Pin or unpin an existing Codex task in the background by thread IDRead recent status and turn summaries for an existing Codex task by thread ID without opening itcodex_app.set_thread_pinnednorcodex_app.read_threadwas returned.codex_app.set_thread_pinned,codex_app.read_thread,codex_app.list_threads, and other Codex task-management tools, and successfully used the task-reading and messaging functions.The calls and outputs were verified in the tasks’ persisted rollout JSONL, rather than inferred only from their conversational summaries.
Direct no-search callable-registry control
I then gave the original affected task the exact normalized invocation for
codex_app.set_thread_pinned, targeting another existing task withpinned: true, and explicitly prohibited another search. It executed this throughfunctions.exec:The persisted runtime result was:
The target was not pinned by that attempt. In the healthy comparison task,
typeof tools.codex_app__set_thread_pinnedreturned"function". This rules out a search-ranking-only explanation for the affected task: its live executor registry also lacked the normalized callable function.One testing caveat: searching for the fully qualified strings
codex_app.set_thread_pinnedandcodex_app.read_threadreturned zero even in the healthy task. Semantic descriptions were therefore used for the controlled comparison.This adds two details I did not see established together in the existing reports:
Current classification: verified task-specific
tool_searchcatalog and live callable-registry omission. It is not yet established whether the functions are absent from persisted dynamic-tool metadata or lost while constructing the affected task’s live callable registry.This appears related to #25990 and the broader dynamic-tool regression in #29223. Sanitized turn timestamps and tool-search output metadata can be provided privately if useful.