You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] Restarting a Claude-spawned Codex worker after switching Codex accounts launches claude commands. #24103
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.
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.
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.
Activity
orca-discord-issues commentedon Oct 1, 2026
via DiscordWorking on this!
nick-inkeep commentedon Oct 4, 2026
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_KEYandORCA_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; onlysession_idandtranscript_pathdiffer. The server keeps the lastsession_idit hears for the pane:src/main/agent-hooks/server/server-status-update.ts:100-153(v1.4.218):resolveAgentStatusIdentityholds only the visibleagentTypewhile 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 incomingproviderSessionis kept. With a Codex worker under a Claude tab, the record becomesagent: claudeplus the Codex thread id, which produces exactly the command in this report. With a same-type worker (claude -punder Claude) nothing is held at all.transitionHookPresence(src/shared/agent-hook-presence-transition.ts:26: "their hooks update status, never ownership") still passes the worker'sproviderSessionthrough, so the restore id can still be the worker's.codex execworkers, 4 fromclaude -p. In-process subagents never caused it, because their events carry the lead'ssession_id. A worker-induced session switch also drops the tab'slaunchConfig(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 previousproviderSessionand 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 throughapplyNormalizedStatus, 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.
unset ORCA_AGENT_HOOK_ENDPOINT ORCA_AGENT_HOOK_PORT ORCA_AGENT_HOOK_TOKEN ORCA_PANE_KEYto$CLAUDE_ENV_FILE. Claude Code runs that file before every Bash command, but not before hooks.~/.codex/config.toml:Related: #13341 has the same cause, seen as the wrong session icon.
brennanb2025 commentedon Oct 15, 2026
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 execorclaude -pfrom 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 asclaude --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 execorclaude -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 execorclaude -pinstead, 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.