Skip to content

Codex Desktop create_thread from an SSH-host executor can spawn children on local host and lose completion handoffs #30626

Open

Description

@chac4l

What version of the Codex App are you using (From "About Codex" dialog)?

Codex Desktop app: 26.623.70822 (released 2026-06-29).

Observed in affected SSH session metadata:

  • Codex Desktop originator
  • SSH-side Codex CLI active in the incident: 0.142.3
  • affected session cli_version: 0.142.3
  • clarification: the SSH-side CLI process had not yet been restarted after the update to 0.142.4, so the active runtime for this incident was still 0.142.3

What subscription do you have?

Unknown from the agent/tool context.

What platform is your computer?

Codex Desktop with connected SSH projects/hosts.

Sanitized topology:

  • Parent/executor thread was running on a remote SSH host, hostId=remote-ssh-discovered:<host>, cwd=/root.
  • Two child threads were created on the local desktop host instead, hostId=local, with Windows-style Codex work directories.
  • A third related child thread was created correctly on the remote SSH host.

What issue are you seeing?

When a Codex Desktop thread running on an SSH project/host acts as a thread executor/orchestrator and creates worker threads, some children can be created on the local desktop host instead of the same SSH host as the executor.

In the observed incident, the executor was on an SSH host and attempted to split work into background child threads. The resulting topology was mixed:

  • Executor: remote SSH host, thread id prefix/suffix 019f152e...05ed8
  • Child A: local host, thread id prefix/suffix 019f1547...dab2
  • Child B: local host, thread id prefix/suffix 019f1547...dd5
  • Child C: remote SSH host, thread id prefix/suffix 019f1548...9519

This was surprising because the executor itself was running on SSH and the task context/path only made sense on the remote host. The two local children did not have the remote checkout/runtime available, so they had to reason around the missing remote environment instead of directly auditing the intended system.

There was a second coordination failure: completion handoffs were not reliably sent back to the executor automatically. The local child threads received codex_delegation inputs containing a source_thread_id, completed their work, but the executor only received the handoffs after manual user intervention asking the children to call send_message_to_thread to the source/executor thread. One nested remote child also needed a manual correction before its report reached the executor directly.

This makes cross-thread orchestration unreliable in SSH projects: workers may run on the wrong machine, and the parent may stall or continue without all worker reports unless the user notices and manually routes the handoff.

What steps can reproduce the bug?

A minimal sanitized reproduction shape:

  1. In Codex Desktop, open or create a thread on a saved SSH project/host.
  2. Ask that SSH-host thread to act as an executor and create multiple background worker threads for the same remote project/runtime.
  3. Have the executor create child threads with create_thread for read-only worker tasks. In the observed case there was no matching local project for the remote repo, and some children were created as projectless/local threads while one related child was created on the SSH host.
  4. Let the children complete.
  5. Inspect thread list / thread metadata.

Actual observed result:

  • Parent/executor stayed on hostId=remote-ssh-discovered:<host>.
  • Two direct child workers appeared under hostId=local with Windows local Codex work directories.
  • One related nested worker appeared on the remote SSH host.
  • Local workers lacked access to the remote Linux checkout/runtime.
  • Workers did not all send completion notices back to the executor without manual user prompts to call send_message_to_thread.

What is the expected behavior?

For thread orchestration started from an SSH-host executor:

  1. Child threads should default to the executor's current host/project unless the tool call explicitly selects another host.
  2. If the app cannot infer the remote host/project, create_thread should fail closed or require an explicit host/project selection rather than silently creating local children.
  3. create_thread results should expose enough host/thread identity for the parent to know where each child actually landed.
  4. A child spawned via codex_delegation with a source_thread_id should have a reliable built-in way to report completion to the source thread, or the product should make explicit that manual send_message_to_thread is required.
  5. If send_message_to_thread needs a hostId, the delegation/source metadata should preserve enough host context to route the response without guessing.

Additional information

Related or adjacent issues I found before filing:

Sanitized evidence was checked through list_threads / read_thread only. I am intentionally not attaching raw logs, full prompts, repository paths beyond generic host/cwd shape, business data, secrets, or full thread contents.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    app-serverIssues involving app server protocol or interfaces
    subagentIssues involving subagents or multi-agent features
    on Jun 29, 2026
  2. chac4l commented on Jun 29, 2026

    @chac4l
    Author

    Version correction from the affected environment:

    • Codex Desktop app: 26.623.70822, released 2026-06-29
    • SSH-side Codex CLI involved in the incident: 0.142.3

    This supersedes the "not visible from agent/tool context" app-version note in the original report. The affected session metadata also showed cli_version: 0.142.3.

  3. chac4l commented on Jun 29, 2026

    @chac4l
    Author

    Additional version clarification: the SSH-side runtime was still 0.142.3 because the Codex CLI process on the SSH host had not yet been restarted after updating to 0.142.4. So the active runtime involved in this incident should be read as 0.142.3, even if 0.142.4 was available/installed afterward.

  4. mppcoder commented on Jul 13, 2026

    @mppcoder

    Additional reproducible evidence from Codex Desktop 26.707.6957.0 (sanitized, 2026-07-13):

    Topology:

    • parent task: saved SSH project, Linux cwd /projects/<repo>;
    • desired Windows VM project: C:\Users\MppCoder\Documents\Vita-route local;
    • another connected Windows desktop profile: C:\Users\HUAWEI.

    Observed from one create_thread delegation using a projectless target:

    1. The returned thread ID resolved through read_thread to a task under C:\Users\MppCoder\Documents\Codex\....
    2. The same delegation also appeared as a separate local task under C:\Users\HUAWEI\Documents\Codex\....
    3. list_threads exposed the HUAWEI copy, while direct read_thread of the returned ID exposed the MppCoder task.
    4. The wrong-host copy correctly stopped at a read-only USERPROFILE gate before UI or writes, but this duplicate placement could have caused unsafe double mutation without that application-level gate.
    5. list_projects advertised the saved MppCoder project and returned its Windows path as projectId; calling create_thread with that exact returned projectId immediately failed with Unknown projectId ... Call list_projects to find available projects.

    Local fail-closed workaround:

    • never use projectless creation for VM acceptance when multiple Windows hosts are connected;
    • require exact USERPROFILE, resolved user-profile folder, cwd/project path, AVD and app/window identity before any UI/write;
    • do not require HOME on Windows;
    • when the saved-project ID is rejected, reuse an existing task whose direct read_thread metadata proves the correct VM/profile and continue it via exact threadId;
    • mark every wrong-host duplicate as zero-mutation excluded evidence.

    Expected product behavior remains: a single explicit destination, no duplicate local tasks, and a projectId returned by list_projects must be accepted by create_thread or fail with an actionable host-availability reason.

  5. bgustafson92 commented on Jul 16, 2026

    @bgustafson92

    Additional reproduction from a three-machine Codex Desktop Remote Control workflow.

    • Codex desktop app: 26.707.91948 (build 5440)
    • Codex CLI/runtime: 0.144.5

    Working control

    This project-scoped topology worked:

    Controller Mac
        └── controls parent task on Remote Mac
                └── creates project task on Remote Windows computer
    

    The Windows destination project appeared in the controller/orchestrator’s list_projects results. The parent used its returned projectId, and the child executed on the intended Windows computer.

    This indicates that project-scoped routing works when the orchestrator’s project registry contains the remote destination project.

    Projectless failure

    This topology was unreliable:

    Controller Mac
        └── controls parent task on Remote Mac
                └── creates projectless child
    

    Expected: the projectless child inherits the parent’s Remote Mac execution host.

    Observed: some projectless children executed on the Controller Mac instead.

    Each child had a fail-closed hostname check, so incorrectly placed tasks stopped before creating or modifying files.

    Project-scoped children appear to receive destination identity through their projectId. Projectless children have no equivalent host association and may fall back to the computer displaying the UI.

    Thread-ID mismatch

    In a later attempt:

    • create_thread returned IDs that could not be resolved through read_thread or archived directly.
    • list_threads exposed the corresponding tasks under different canonical IDs.
    • After resolving those IDs, the tasks reported execution on the intended Remote Mac.

    Requested behavior

    For projectless child creation:

    1. Inherit the parent task’s execution host by default.
    2. Allow an optional explicit destination host.
    3. Fail closed if the selected host is unavailable.
    4. Return the canonical threadId and actual execution host.
    5. Preserve the parent’s host identity in delegation metadata.

    In short: project-scoped routing works when list_projects supplies a destination project, while projectless routing lacks reliable host affinity in a multi-host setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingremotesubagentIssues involving subagents or multi-agent features

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions