Skip to content

[Bug] Restarting a Claude-spawned Codex worker after switching Codex accounts launches claude commands. #24103

Open

Description

@orca-discord-issues

mnsxyz mnsxyz via Discord

Repro:

  1. Start Claude in Orca.
  2. Claude spawns a Codex worker.
  3. Work in that Codex worker.
  4. Switch Codex account in Orca.
  5. Restart the Codex worker/session.

Actual:

claude '--dangerously-skip-permissions' '--resume' '01a0f103-942a-7940-abef-bd2bb16b2e92'

Then Claude returns:

No conversation found with session ID: 01a0f103-942a-7940-abef-bd2bb16b2e92

However, the same ID works correctly with:

codex resume 01a0f103-942a-7940-abef-bd2bb16b2e92

and restores the exact Codex session.

So Orca appears to be mixing the Claude parent agent's resume command with the Codex worker's session ID during restart after an account switch.

Activity

  1. orca-discord-issues commented on Oct 1, 2026

    @orca-discord-issues
    Author

    Brennan Brennan via Discord

    Working on this!

  2. nick-inkeep commented on Oct 4, 2026

    @nick-inkeep

    We hit the same failure (claude --resume <codex thread id> → "No conversation found") without any account switch, so the switch may be incidental. Here is the root cause as we traced it in v1.4.218; it is still present in v1.4.220.

    Mechanism. Any agent started from inside an Orca terminal inherits the tab's ORCA_PANE_KEY and ORCA_AGENT_HOOK_*. A worker the lead starts (codex exec, claude -p, or a script that runs them) therefore fires Orca's global hooks with the parent tab's identity. Its hook posts are otherwise indistinguishable from the lead's: same keys, same pane, tab and launch metadata; only session_id and transcript_path differ. The server keeps the last session_id it hears for the pane:

    • src/main/agent-hooks/server/server-status-update.ts:100-153 (v1.4.218): resolveAgentStatusIdentity holds only the visible agentType while the parent is active (src/shared/agent-status-identity.ts:75: "child agent CLIs inherit ORCA_PANE_KEY … do not let a nested hook steal the pane's visible identity"). The incoming providerSession is kept. With a Codex worker under a Claude tab, the record becomes agent: claude plus the Codex thread id, which produces exactly the command in this report. With a same-type worker (claude -p under Claude) nothing is held at all.
    • v1.4.220 (fix(agent-status): preserve hook presence when process checks cannot answer (step 1 of 3) #23947) adds process ownership, but transitionHookPresence (src/shared/agent-hook-presence-transition.ts:26: "their hooks update status, never ownership") still passes the worker's providerSession through, so the restore id can still be the worker's.
    • Restore uses whatever was recorded last before the app quit. Across Orca's saved records on one machine we found 16 worker session ids recorded as tab sessions: 12 from codex exec workers, 4 from claude -p. In-process subagents never caused it, because their events carry the lead's session_id. A worker-induced session switch also drops the tab's launchConfig (model and permission flags).

    Minimal fix we'd suggest. In transitionHookPresence, when a live owner exists and the sender is not provably that owner's process, keep the previous providerSession and the owner's agent type, and update only status. Copy the previous id rather than dropping it: a dropped id leaves the tab with nothing to resume. Both live posts and spool replay go through applyNormalizedStatus, so one change covers both. Codex-owned tabs would also need the Codex hook command to report the agent's process, as #23947 now does for Claude. Checking the recorded id against the tab's agent type (a Codex thread id on a Claude tab) before building the resume command would catch anything left over.

    Workaround on the user side. We verified this end to end against Orca's real hook scripts with a fake listener: the lead keeps reporting, and workers post nothing.

    • Claude leads: a SessionStart hook that appends unset ORCA_AGENT_HOOK_ENDPOINT ORCA_AGENT_HOOK_PORT ORCA_AGENT_HOOK_TOKEN ORCA_PANE_KEY to $CLAUDE_ENV_FILE. Claude Code runs that file before every Bash command, but not before hooks.
    • Codex leads, in ~/.codex/config.toml:
      [shell_environment_policy.filters]
      "ORCA_AGENT_HOOK_*" = "exclude"
      "ORCA_PANE_KEY" = "exclude"

    Related: #13341 has the same cause, seen as the wrong session icon.

  3. brennanb2025 commented on Oct 15, 2026

    @brennanb2025
    Contributor

    Thanks for the report, and thanks @nick-inkeep for tracing the cause.

    What's happening: when an agent in an Orca terminal runs another agent CLI itself, for example Claude running codex exec or claude -p from its shell tool, the inner agent inherits the tab's Orca settings and reports into that tab as if it were the tab's own agent. While the inner agent is running, Orca can save its conversation ID on the outer agent's tab. If Orca quits, restarts or sleeps the workspace during that window, the tab comes back as claude --resume <codex id>, and Claude reports "No conversation found". Switching Codex accounts isn't required to hit it.

    Why it's hard to fix in Orca: the inner agent's reports look the same as the outer agent's, with the same tab and the same settings. Only the conversation ID differs. To know which one to keep, Orca has to know which process sent each report. Today it can check that reliably only for Claude on a local Mac or Linux machine, not for Codex, on Windows, or over SSH. The same reports also have to let a new agent take over the tab once the previous one has exited.

    What we recommend: instead of having the agent run other agents with codex exec or claude -p, use Orca's orchestration (/orchestration). Each worker then runs in its own tab with its own identity, so every tab resumes its own conversation after a restart.

    If you've already hit it: the conversation isn't lost. Run codex resume <id> with the ID from the failed command, as you found, and the Codex session comes back.

    Would orchestration work for your setup? If there's a reason you're running workers through codex exec or claude -p instead, such as a skill or plugin that calls them, or something orchestration doesn't cover yet, let us know. That would help us decide what to change.

  4. self-assigned this
    on Oct 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions