Codex app thread-management tools not exposed despite thread creation being available

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

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_thread
  • send_message_to_thread
  • fork_thread
  • list_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_thread
  • send_message_to_thread
  • fork_thread
  • list_threads
  • read_thread
  • set_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_search
  • create thread tools unavailable
  • tool_search missing tools
  • thread management tools
  • multi_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.

View original on GitHub ↗

5 Comments

github-actions[bot] contributor · 2 months ago

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

  • #29223

Powered by Codex Action

johnsilvavlogs · 2 months ago

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_thread was ranked outside the first discovery page even when the exact query included create_thread.

Environment observed from the local machine:

  • Codex CLI: codex-cli 0.142.1
  • Codex Desktop app: 26.623.42026 / build 4514
  • Platform: macOS

Repro notes:

  1. In a manager-style Codex Desktop task, the assistant needed to create visible worker threads.
  2. Tool discovery was run with the exact Loop Engineering query: 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, with limit: 10.
  3. The returned codex_app tool surface included thread/project tools such as read_thread, send_message_to_thread, set_thread_title, set_thread_pinned, set_thread_archived, list_projects, list_threads, fork_thread, handoff_thread, and get_handoff_status, but did not include create_thread.
  4. list_projects was available and its description explicitly said to use the returned projectId with create_thread, making the exposed surface internally inconsistent.
  5. The assistant concluded create_thread was unavailable and used same-directory fork_thread as 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.
  6. Retrying the same exact discovery query with a larger limit (limit: 12) exposed create_thread as an additional result.

Expected behavior:

  • If a query contains the literal token create_thread, create_thread should be surfaced ahead of adjacent utilities, especially below normal limits such as 8-10.
  • Thread-management tools should probably be exposed as a coherent bundle: exposing list_projects with documentation that references create_thread while hiding create_thread leads agents to a false unavailable conclusion.
  • If ranking/limits can omit critical exact-name tools, the tool instructions should not require agents to infer absence from a capped discovery call.

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.”

ysjblog · 1 month ago

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

  • macOS (Darwin 25.5.0)
  • ChatGPT Desktop app 26.707.91948, bundled engine codex-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 with deferLoading: true, but no tool_search is exposed in the callable surface, so the agent has no way to load them. Only navigate_to_codex_page, read_thread_terminal, and load_workspace_dependencies are directly callable.

Flag state that looks like the direct cause (from the bundled binary's codex features list on 0.144.5):

js_repl                              removed            false
js_repl_tools_only                   removed            false
tool_search                          removed            false
tool_search_always_defer_mcp_tools   removed            true

i.e. tools are still always deferred, but both loading paths (tool_search and the older js_repl runtime) 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/list all succeeded).
  • Jul 16: Desktop auto-updated 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 called create_thread and produced a GUI-visible child task, while other fresh sessions only received exec_command with the thread tools stuck in the deferred catalog.

Ruled out locally (with counter-evidence)

  • Instruction-file (AGENTS.md) changes: a session created before any edits, loaded with the unmodified rules, already lacked the tools.
  • Account switch: sessions after the switch still succeeded at least once.
  • Local config: 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.

emanuelsan · 1 month ago

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

  • Codex Desktop: 26.721.41059 (released 2026-07-24), build 5848
  • Bundled app server: 0.146.0-alpha.3.1
  • macOS on Apple silicon; Darwin 25.4.0 arm64
  • AC display-sleep timeout: 60 minutes
  • A long-running caffeinate process held PreventUserIdleSystemSleep and PreventDiskIdle, but not PreventUserIdleDisplaySleep. The Mac remained awake while its displays were allowed to turn off.

Controlled sequence

  1. After updating and fully restarting Codex, list_threads and read_thread both worked in an existing long-lived task.
  2. macOS subsequently recorded Display is turned off at 2026-07-26 21:54:52 +0300. Full idle system sleep remained prevented.
  3. While the displays were still off:
  • list_threads returned No handler registered for tool: list_threads;
  • send_message_to_thread returned No handler registered for tool: send_message_to_thread;
  • desktop/app-server logs nevertheless showed the underlying thread/list and destination turn/start operations completing successfully with no error;
  • read_thread succeeded and proved that the supposedly failed message had actually been delivered;
  • the bundled Chrome plugin also remained functional.
  1. The display remained off overnight for approximately 10 hours 48 minutes. A pre-wake list_threads probe still returned the no-handler error.
  2. Waking the display and successfully unlocking through the macOS login screen did not restore the handler. list_threads continued returning No handler registered, while another Codex app tool, read_thread_terminal, reached its handler normally.
  3. Restarting Codex—without changing the power configuration—immediately restored list_threads, read_thread, send_message_to_thread, and message readback. The ChatGPT/Codex process PID and assertion age reset; the existing caffeinate process and macOS power configuration did not.

Relevant desktop-log evidence

Around the failed cross-thread message, logs recorded:

documentVisibilityState=hidden

previousResumeState=needs_resume

The 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 found and Received 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 query argument for list_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.

emanuelsan · 1 month ago

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_search results before any invocation is possible.

Environment

  • Codex Desktop 26.721.41059, released July 24, 2026
  • Bundled Codex CLI: codex-cli 0.146.0-alpha.3.1 (/Applications/ChatGPT.app/Contents/Resources/codex --version)
  • Darwin 25.4.0 arm64
  • Observed July 27, 2026

Controlled comparison

  1. I fully restarted Codex.
  2. An existing long-lived task executed these semantic searches:
  • Pin or unpin an existing Codex task in the background by thread ID
  • Read recent status and turn summaries for an existing Codex task by thread ID without opening it
  1. Both searches completed, but returned only unrelated connector tools. Neither codex_app.set_thread_pinned nor codex_app.read_thread was returned.
  2. I created a new same-directory fork of the affected task after the restart and repeated the identical searches. The fork returned effectively the same unrelated inventories and no Codex task-management tools.
  3. A separate task in the same app and workspace ran the identical queries at approximately the same time. It discovered 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 with pinned: true, and explicitly prohibited another search. It executed this through functions.exec:

await tools.codex_app__set_thread_pinned({
  threadId: "<redacted-existing-task-id>",
  pinned: true
});

The persisted runtime result was:

TypeError: tools.codex_app__set_thread_pinned is not a function

The target was not pinned by that attempt. In the healthy comparison task, typeof tools.codex_app__set_thread_pinned returned "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_pinned and codex_app.read_thread returned 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:

  • restarting Codex did not refresh the affected existing task’s discovery catalog;
  • creating a new fork from that affected task did not provide a clean catalog, while an unrelated task on the same runtime remained healthy.

Current classification: verified task-specific tool_search catalog 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.