spawn_agent / followup_task message payload never reaches the sub-agent (encrypted_content is dropped)
What version of the Codex App are you using (From “About Codex” dialog)?
26.803.41515(build 6321
What subscription do you have?
N/A (using API key / custom provider)
What platform is your computer?
Darwin 25.6.0 arm64 arm
What issue are you seeing?
When the root agent calls spawn_agent or followup_task, the sub-agent is created and its turn is triggered, but the
message payload never appears in the sub-agent's context. The sub-agent only sees system-level content (skills
instructions, permissions, AGENTS.md, environment context) and replies with a generic "waiting for task" message.
The framework constructs the inter-agent communication object with an empty content field and stores the payload
exclusively in encrypted_content. The receiving side builds its turn input from content only
(user_input_count=0) and never decrypts/consumes encrypted_content; no decryption error is logged, so the payload
is silently dropped.
Reproduced on the Codex desktop app 26.803.41515 and in a fresh codex exec CLI process (0.147.0-alpha.6.5), with
both fork_turns=none and fork_turns=all. Full reproduction steps, raw log evidence, and a downloadable evidence
archive (bug-evidence.zip) are in the report below.
What steps can reproduce the bug?
Minimal reproduction (desktop app):
- In any project directory, open Codex (ChatGPT desktop app).
- From the root agent, run:
spawn_agent(task_name="ping", message="Reply with exactly: PONG", fork_turns="none")
- Wait for the spawned agent's turn to complete.
- Actual result: the sub-agent replies with a generic "waiting for task" message
(e.g. "已就绪,等待任务内容。请把要处理的写作任务发给我…") instead of "PONG".
Follow-up reproduction (same session):
- Run: followup_task(target="ping", message="Reply with exactly: PONG")
- Actual result: the follow-up turn again completes with a generic
"waiting for task" reply; the message text never reaches the sub-agent.
CLI reproduction (fresh process):
- Run:
/Applications/ChatGPT.app/Contents/Resources/codex exec --json --skip-git-repo-check \
"用 spawn_agent 派生一个子 agent(task_name=cli_ping, fork_turns=none, message='Reply with exactly: PONG'),等待
它回复,然后原样报告它第一条回复的文本。如果 spawn_agent 工具不可用或派生失败,明确说明原因。"
- Actual result: the CLI spawns the sub-agent successfully, but the sub-agent
explicitly reports that its turn input contained no task text (it even waited
15s on the mailbox with no queued message).
Expected result in all cases: the sub-agent's first reply is exactly "PONG".
What is the expected behavior?
When the root agent calls spawn_agent, the spawned sub-agent's first turn should contain the message text as a user
input, so the sub-agent can see and execute the task.
When the root agent calls followup_task, the message should appear in the target agent's next turn.
More generally: the payload should not be silently dropped. If encryption of the message is required but decryption on
the receiving side is not possible, the framework should surface an explicit error instead of delivering a turn with
empty input.
Additional information
A few things that should make this easier to triage:
- Evidence archive: bug-evidence.zip is attached to this issue. It contains verbatim (raw, unmodified) log extracts,
not paraphrases — sender-side tool calls, the framework's InterAgentCommunication records, the sub-agent's session
messages, the receiver's user_input_count=0 turn logs, and the CLI reproduction. The report's "Log evidence" section
maps each file to its excerpt.
- The failure has been reproduced continuously since 2026-08-09 across multiple sessions, in both the desktop app and
the bundled CLI, with fork_turns=none, fork_turns=all, spawn and follow-up. It is not configuration- or
fork_turns-related.
- The wake-up path works: the sub-agent is created, its turn is triggered, and
SubAgentActivity/
inter_agent_communication dispatch are logged normally. Only the payload delivery is broken.
- Direction asymmetry: sub-agent → root replies use plaintext
contentand are delivered; only root → sub-agent task
messages fail (they are stored in encrypted_content with empty content and never rendered into the model turn).
- No decryption error is ever logged — the
encrypted_contentpayload is never consumed, which suggests a missing/
not-wired decryption step on the receiving side (or the sender should populate content for same-host communication).
- Local config experiment already performed: adding
[features.multi_agent_v2] wait_agent_enabled = trueand
retesting in a fresh codex exec process did not change the behavior; the config was rolled back.
- Impact: any workflow that delegates work via spawn_agent / followup_task is unusable. Real-world case: an 8-agent
writing pipeline (awesome-novel, .codex/agents/*.toml + order-file protocol) blocks at the first spawn_agent because
the sub-agent never receives the order path. With fork_turns="all", sub-agents silently replay the parent's history
instead, which can cause unintended actions.
4 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Same root cause as #36586 / #34833: the task is stored only in
encrypted_contentand DeepSeek drops that block, so the child sees system context but no payload. We reproduced this on codex-cli 0.146.0 with wire captures and also found that even a plaintextinput_textinside theagent_messageitem is ignored by DeepSeek (its Responses compatibility table only acceptsmessage,function_call,function_call_output,reasoning, andweb_search_callinput item types).A local patch that delivers V2 spawn / followup_task / send_message payloads as plain user messages for non-OpenAI providers is verified end-to-end (spawn ->
PONG, followup ->PONG2) and published here: https://github.com/CCanxue/codex-deepseek-subagent-fixReproduced again on 2026-08-11 with Codex Desktop (session_meta: cli
0.147.0-alpha.6.6,model_provider: custom, macOS). Same symptom, plus a few datapoints:Message Type: NEW_TASK ... Payload:followed by an emptycontentblock and<<ENCRYPTED keys=['type','encrypted_content']>>— the plaintext never reaches the child, and no decryption error is logged.spawn_agent(initial message) andfollowup_task,fork_turns="none"andfork_turns="all", Chinese and pure-ASCII payloads, at sub-agent depths 1–3: the child always sees only system/env/AGENTS.md content and replies with a generic "waiting for task".fork_turns="all"does pass the parent's conversation history (the child can pick up the task from the inherited context), but the spawn message itself is still dropped — consistent with this report.FINAL_ANSWERreaches the parent fine; only parent → child task payloads are lost.Impact here: an architecture-review workflow's Explore sub-agent never received its brief, and I had to run the exploration in the root agent instead. Any delegation workflow is blocked until this is fixed. Happy to attach rollout log excerpts if useful.
The "never decrypts/consumes
encrypted_content" observation is by design — which is exactly why the failure is silent.InterAgentCommunication::to_model_input_itemrenders the payload as a plaintext header ("Message Type: NEW_TASK … Payload:\n") followed by anEncryptedContentcontent item (https://github.com/openai/codex/blob/1f41cc5d92/codex-rs/protocol/src/protocol.rs#L813-L846). Codex-side decryption never happens anywhere: the blob is meant to be decrypted server-side when the sub-agent's request reaches the OpenAI backend. So whenever the receiving request lands somewhere that can't decrypt it — different provider, API-key auth without the originating session's context, model-family/retention mismatch — the sub-agent's model sees the header with an empty payload and answers "waiting for task." No error is possible client-side because the client never inspects the blob.This makes your report the third face of one defect: #38656 (cross-provider child tasks get an undecryptable message) and #37858 (Ultra multi-agent dead with API-key
model_providers) fail the same way.Fix outline: (1) the plaintext path already exists (
content+new()vsnew_encrypted()—#L755-L791); choose it whenever sender and receiver aren't both on the encrypting backend, or at minimum fall back to it when they differ; (2) validate decryptability at spawn time and fail loudly instead of letting the sub-agent run a full turn against an empty payload; (3) log something when anEncryptedContentitem ships to a non-OpenAI-backed request — today that's the exact signature of this bug and it's invisible.