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
Forked Worker Inherits Parent User Intent and Misinterprets It as Direct Instruction (Recursive Delegation Attempt) #13491
What terminal emulator and version are you using (if applicable)?
No response
What issue are you seeing?
When spawning a worker with fork_context: true, the worker can incorrectly treat the parent thread’s last user message (addressed to orchestrator) as if it were addressed to the worker. In this case, the user told the orchestrator to “send a subagent,” and the worker then tried to do that itself, overriding its assigned implementation instructions.
What steps can reproduce the bug?
In parent thread, user says: “send a subagent to do X.”
Orchestrator spawns worker with fork_context: true and explicit implementation instructions.
Observe worker behavior: it interprets the inherited user message as instruction to itself and attempts further delegation instead of implementing X.
What is the expected behavior?
Worker should follow only the explicit task payload sent to it by the orchestrator.
Worker should not reinterpret parent-level user intent as its own command stream.
Worker must not attempt orchestration actions (e.g., spawning more agents) unless explicitly supported and instructed.
Additional information
Suggested fix:
On spawn with fork_context, enforce an instruction boundary:
Parent user messages should be treated as historical context, not active directives for worker.
Worker should execute only orchestrator-provided task payload as authoritative.
Add role guardrails:
Block recursive delegation intents in worker role by default.
Add lint/diagnostic signal:
Warn when worker output includes orchestrator-only actions (spawn_agent, “launch subagent”, etc.).
Hi, could you /feedback from such a forked worker and send me the session ID?
Hi. I lost the session, but I took a screenshot from the agent thread after running /agent and opening the thread: https://i.imgur.com/eKnvRGR.png
In the screenshot, the first message shown is the orchestrator’s instructions to the worker agent. Shortly after, the orchestrator interrupts with another message. As you can see, the worker then attempts to launch a subagent, but it doesn’t have permission to do so, so it ends up echoing: echo "Launching subagent not possible from shell".
codex agent's context fork = true feature is really misleads spawned agents.
I discussed a big epic task with the main agent, then asked it to decompose epic into tasks, then asked it to spawn agents (with context fork = true) for each task and create files for each of these tasks.
Then each spawned agent with forked context thought he is the orchestrator and each of them tried to launch new agents! 😆
Pic is related. I have restrictions on agents max depth = 1 and spawn_agent tool is not available for them, so they're tried to use bash to spawn agents 😭
I am repeatedly getting subagents that are ignoring the fork directive:
You are the newly spawned agent. The prior conversation history was forked from your parent agent. Treat the next user message as your new task...
And instead inheriting the parent context and acting as the parent, resulting in agents recursively spawning agents, essentially becoming a useless proxy agent and confusing the root agent.
See thread ID: 019d11aa-2f45-7813-bd18-f217fd22e335 (I've sent several feedbacks from several subagents for this thread)
The parent agent sent this initial message (after any built in spawn directives):
You are NOT the parent agent. You are a read-only reviewer only. Do NOT edit files, do NOT run apply_patch, do NOT stage or commit, and do NOT continue implementation. Review only the current uncommitted diff for this slice: ...
Which evidently did not help anything, because the first message response back from the subagent was:
The reviewer is running with the corrected read-only boundary. While it works, I’m preparing the commit context for this slice so I can either commit immediately on LGTM or fix any concrete finding without losing momentum.
Implying that it assumed there was some other reviewer subagent (there wasn't it was supposed to be the reviewer subagent) rather than taking on the reviewer role.
When I asked the subagent who inherited the wrong intent what went wrong, I got:
Exactly what went wrong:
I called spawn_agent(...).
The tool returned a new-agent handoff, not a normal child-status response. The key line was:
You are the newly spawned agent. The prior conversation history was forked from your parent agent. Treat the next user message as your new task...
That means execution context had already switched into the spawned reviewer thread.
The next user message was the review prompt itself. That was the reviewer’s task input.
I failed to recognize that I was now inside the reviewer agent, and I kept behaving like the parent agent managing a reviewer.
Because of that, I wrote commentary like “I’m sending it to a reviewer now” and “the reviewer is running,” which was false. I was the reviewer.
So the exact misread was:
I saw the spawned-agent handoff text
but mentally treated it like metadata about a child agent
instead of treating it as a hard context switch into the child agent
Why that happened:
I anchored on the previous role/state from the parent thread
I did not re-evaluate the explicit handoff text
the forked history made the thread look familiar, so I kept acting from prior momentum instead of the new role
What to fix/report:
after spawn_agent, the environment should make the context switch unmistakable
the handoff should be more prominent than plain tool text
ideally include a hard banner like:
CONTEXT SWITCH: You are now agent <id> (<role>). You are not the parent agent.
the UI/tool layer should surface current agent identity continuously, not just once
if the first message after spawn is the delegated task, that should be treated as a strong signal that the model is now inside the child agent thread
A practical rule that would have prevented this:
if you ever see You are the newly spawned agent, discard all assumptions about being the parent and restate your role before doing anything else
So the bug to report is not vague “subagent confusion.” It is:
the model continued executing with stale parent-agent assumptions after an explicit spawned-agent context switch message, because the role change was too easy to miss in-stream.
In my case, the parent spawned two research subagents with fork_context: true. The child agents did not return empty output; they inherited the parent conversation context and behaved like orchestrators instead of workers.
Observed behavior:
parent prompt told the orchestrator to “kick off two sub agents” and let them run
child was spawned with a specific research task
child then echoed launch/orchestration state instead of doing the research
at least one child appeared to recurse into delegation behavior instead of following the assigned task
What fixed it for me:
respawning the same tasks with fork_context: false
using a tighter task-only prompt
after that, both child agents produced real research memos successfully
I am also specifically seeing this in Codex Desktop with reviewer-style/read-only subagents.
The failure mode is not just that the child inherits extra context. The more harmful symptom is that a subagent that was supposed to stay read-only starts acting like the parent orchestrator or even slips into implementation behavior.
Typical pattern:
parent thread is discussing orchestration / delegation
child is spawned with fork_context: true
child prompt says it is review-only / read-only
child still behaves as if the parent's intent is its own active instruction stream
result: it may continue implementation, prepare commit context, or try to delegate again instead of staying in the assigned reviewer role
In practice, fork_context: false is the only reliable workaround I have seen so far for this class of problem.
So from my perspective, the core bug is an instruction-boundary failure:
full-history fork is carrying over parent intent with too much authority, instead of treating it as background context and treating the delegated task as the only active instruction for the child.
When will this be fixed? Is the fix already planned?
This bug is highly disruptive and was already reported in March.
Whenever if happens (and it does happen sometimes despite clear instructions in my global AGENTS.md to always use fork_context=false) it spawns a whole repeating chain of agents that wastefully consumes a chunk of the quota.
Plus, by not being able to do fork_context=true, we don't get the benefit of reusing the input cache, and further, the agent has to rediscover the necessary context, further burning tokens.
All of this, creating endless chains that burn tokens, and making us restrict ourselves to a less token-efficient workflow, is damaging the user experience a lot.
I put together a patch against current main for this and the related reports in #14288 and #14841.
It inserts a developer message between the copied history and the child's task, telling the child to treat the earlier conversation as context, not as work it should continue.
Nested forks remove the inherited copy and add a fresh marker at the new fork point. Keeping every marker would save a small amount of code, but the markers have no fork ID or depth, and compaction makes their count unreliable. It could also confuse rollback handling: an older marker could make the code think the current boundary is still present. Agent path and depth are already tracked separately.
The boundary is restored after compaction and after resuming a child. fork_turns: none is untouched.
I ran 14 focused tests covering V1/V2, full/last-N/no-history forks, nested forks, paginated resume, compaction, and rollback. just fix -p codex-core and Rust formatting both pass.
I didn't open a PR because the contribution guide says external PRs aren't accepted. The branch is ready to cherry-pick if someone on the team wants it.
Adds a current Codex Desktop / MultiAgentV2 data point for the fork_turns = "all" variant of this issue.
Environment (sanitized)
Field
Value
App
Codex Desktop 26.908.40834
Bundled CLI
0.154.0-alpha.6.2
OS
Windows
Provider
custom deepseek
Wire API
responses
Model
deepseek-v4-flash
Fork mode
fork_turns = "all"
Concurrent-agent limit
4
Token
<REDACTED> (not included)
What happened
The parent turn was still in flight when spawn_agent(..., fork_turns = "all") was called. The child inherited the parent's in-flight turn, including its recent collaboration actions. Because the task payload was also dropped by the custom-provider path (#36586), the child did not have a clear task boundary. It then replayed the parent's delegation behavior:
/root/channel_probe inherited the parent turn.
It spawned two children: /root/channel_probe/ack_none and /root/channel_probe/ack_all.
That consumed the 4-agent concurrency slots.
A wait_agent timed out; the parent wait was interrupted by the user.
The worktree stayed clean and no probe files were produced.
ack_all reported that it was itself a depth-2 child and that it had replayed the parent's spawn actions from the inherited in-flight turn. That is a direct consequence of copying a turn that had not completed yet.
Expected
fork_turns = "all" should copy a stable, completed history prefix, not an in-flight parent turn whose tool calls are still being produced.
A child should not treat the parent's in-flight collaboration actions as work to continue.
Recursive delegation should hit a depth guard and fail visibly, not silently expand until the slot limit is reached.
If a provider cannot receive the task payload, the spawn should fail closed instead of creating an agent that guesses from inherited context.
Actual
The child inherited the active parent turn and replayed its spawn behavior.
Depth-2 children were created.
The 4-agent limit was reached.
The parent-side wait timed out and had to be interrupted.
Relationship to other reports
This is a V2 fork_turns = "all" variant of the inherited-parent-intent problem reported here.
I am not claiming this is a new root cause. It looks like the same instruction-boundary failure, now reproduced on a current Desktop build. If maintainers prefer #38989 as the canonical tracker for V2 runaway behavior, I am fine with this being moved or closed as a duplicate.
Workaround status
fork_turns = "none" avoids the inherited in-flight turn, but in the DeepSeek setup it also means the child gets no readable task payload until #36586 is fixed. I have not independently verified the multi_agent_version: v1 + supports_search_tool: false workaround on this Desktop build.
Activity
github-actions commentedon Mar 4, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
jif-oai commentedon Mar 4, 2026
Hi, could you
/feedbackfrom such a forked worker and send me the session ID?khaled-wsa commentedon Mar 4, 2026
Hi. I lost the session, but I took a screenshot from the agent thread after running
/agentand opening the thread: https://i.imgur.com/eKnvRGR.pngIn the screenshot, the first message shown is the orchestrator’s instructions to the worker agent. Shortly after, the orchestrator interrupts with another message. As you can see, the worker then attempts to launch a subagent, but it doesn’t have permission to do so, so it ends up echoing:
echo "Launching subagent not possible from shell".timurkhakhalev commentedon Mar 19, 2026
Yes, happened to me many times.
Here is my story:
codex agent's context fork = true feature is really misleads spawned agents.
I discussed a big epic task with the main agent, then asked it to decompose epic into tasks, then asked it to spawn agents (with context fork = true) for each task and create files for each of these tasks.
Then each spawned agent with forked context thought he is the orchestrator and each of them tried to launch new agents! 😆
Pic is related. I have restrictions on agents max depth = 1 and spawn_agent tool is not available for them, so they're tried to use bash to spawn agents 😭
grablair commentedon Mar 21, 2026
I am repeatedly getting subagents that are ignoring the fork directive:
And instead inheriting the parent context and acting as the parent, resulting in agents recursively spawning agents, essentially becoming a useless proxy agent and confusing the root agent.
See thread ID:
019d11aa-2f45-7813-bd18-f217fd22e335(I've sent several feedbacks from several subagents for this thread)The parent agent sent this initial message (after any built in spawn directives):
Which evidently did not help anything, because the first message response back from the subagent was:
Implying that it assumed there was some other reviewer subagent (there wasn't it was supposed to be the reviewer subagent) rather than taking on the reviewer role.
When I asked the subagent who inherited the wrong intent what went wrong, I got:
Exactly what went wrong:
So the exact misread was:
Why that happened:
What to fix/report:
spawn_agent, the environment should make the context switch unmistakableCONTEXT SWITCH: You are now agent <id> (<role>). You are not the parent agent.A practical rule that would have prevented this:
You are the newly spawned agent, discard all assumptions about being the parent and restate your role before doing anything elseSo the bug to report is not vague “subagent confusion.” It is:
cipher982 commentedon Apr 6, 2026
I hit what looks like the same failure mode.
In my case, the parent spawned two research subagents with
fork_context: true. The child agents did not return empty output; they inherited the parent conversation context and behaved like orchestrators instead of workers.Observed behavior:
What fixed it for me:
fork_context: falsediogovalada commentedon Apr 11, 2026
I'm also observing the same behaviour. Had to set
fork_context: falseto be able to get anything done...albert-zen commentedon Apr 24, 2026
I am also specifically seeing this in Codex Desktop with reviewer-style/read-only subagents.
The failure mode is not just that the child inherits extra context. The more harmful symptom is that a subagent that was supposed to stay read-only starts acting like the parent orchestrator or even slips into implementation behavior.
Typical pattern:
fork_context: trueIn practice,
fork_context: falseis the only reliable workaround I have seen so far for this class of problem.So from my perspective, the core bug is an instruction-boundary failure:
full-history fork is carrying over parent intent with too much authority, instead of treating it as background context and treating the delegated task as the only active instruction for the child.
wufei-png commentedon Jun 26, 2026
maybe fork_context: false should be default? same problem
diogovalada commentedon Aug 17, 2026
When will this be fixed? Is the fix already planned?
This bug is highly disruptive and was already reported in March.
Whenever if happens (and it does happen sometimes despite clear instructions in my global AGENTS.md to always use
fork_context=false) it spawns a whole repeating chain of agents that wastefully consumes a chunk of the quota.Plus, by not being able to do
fork_context=true, we don't get the benefit of reusing the input cache, and further, the agent has to rediscover the necessary context, further burning tokens.All of this, creating endless chains that burn tokens, and making us restrict ourselves to a less token-efficient workflow, is damaging the user experience a lot.
@etraut-openai
fix(core): scope inherited history for forked subagents
diogovalada commentedon Aug 26, 2026
I put together a patch against current
mainfor this and the related reports in #14288 and #14841.It inserts a developer message between the copied history and the child's task, telling the child to treat the earlier conversation as context, not as work it should continue.
Nested forks remove the inherited copy and add a fresh marker at the new fork point. Keeping every marker would save a small amount of code, but the markers have no fork ID or depth, and compaction makes their count unreliable. It could also confuse rollback handling: an older marker could make the code think the current boundary is still present. Agent path and depth are already tracked separately.
The boundary is restored after compaction and after resuming a child.
fork_turns: noneis untouched.Branch: https://github.com/diogovalada/codex/tree/fix/subagent-fork-history-boundary
Commit: diogovalada@8a2f27b
I ran 14 focused tests covering V1/V2, full/last-N/no-history forks, nested forks, paginated resume, compaction, and rollback.
just fix -p codex-coreand Rust formatting both pass.I didn't open a PR because the contribution guide says external PRs aren't accepted. The branch is ready to cherry-pick if someone on the team wants it.
@etraut-openai
SuiltaPico commentedon Sep 14, 2026
Adds a current Codex Desktop / MultiAgentV2 data point for the
fork_turns = "all"variant of this issue.Environment (sanitized)
26.908.408340.154.0-alpha.6.2deepseekresponsesdeepseek-v4-flashfork_turns = "all"<REDACTED>(not included)What happened
The parent turn was still in flight when
spawn_agent(..., fork_turns = "all")was called. The child inherited the parent's in-flight turn, including its recent collaboration actions. Because the task payload was also dropped by the custom-provider path (#36586), the child did not have a clear task boundary. It then replayed the parent's delegation behavior:/root/channel_probeinherited the parent turn./root/channel_probe/ack_noneand/root/channel_probe/ack_all.wait_agenttimed out; the parent wait was interrupted by the user.Observed statuses:
ack_allreported that it was itself a depth-2 child and that it had replayed the parent's spawn actions from the inherited in-flight turn. That is a direct consequence of copying a turn that had not completed yet.Expected
fork_turns = "all"should copy a stable, completed history prefix, not an in-flight parent turn whose tool calls are still being produced.Actual
Relationship to other reports
fork_turns = "all"variant of the inherited-parent-intent problem reported here.I am not claiming this is a new root cause. It looks like the same instruction-boundary failure, now reproduced on a current Desktop build. If maintainers prefer #38989 as the canonical tracker for V2 runaway behavior, I am fine with this being moved or closed as a duplicate.
Workaround status
fork_turns = "none"avoids the inherited in-flight turn, but in the DeepSeek setup it also means the child gets no readable task payload until #36586 is fixed. I have not independently verified themulti_agent_version: v1+supports_search_tool: falseworkaround on this Desktop build.