spawn_agent / followup_task message payload never reaches the sub-agent (encrypted_content is dropped)

Open 💬 4 comments Opened Aug 10, 2026 by modoojunko
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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):

  1. In any project directory, open Codex (ChatGPT desktop app).
  2. From the root agent, run:

spawn_agent(task_name="ping", message="Reply with exactly: PONG", fork_turns="none")

  1. Wait for the spawned agent's turn to complete.
  2. Actual result: the sub-agent replies with a generic "waiting for task" message

(e.g. "已就绪,等待任务内容。请把要处理的写作任务发给我…") instead of "PONG".

Follow-up reproduction (same session):

  1. Run: followup_task(target="ping", message="Reply with exactly: PONG")
  2. 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):

  1. 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 工具不可用或派生失败,明确说明原因。"

  1. 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:

  1. 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.

  1. 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.

  1. 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.

  1. Direction asymmetry: sub-agent → root replies use plaintext content and 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).

  1. No decryption error is ever logged — the encrypted_content payload 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).

  1. Local config experiment already performed: adding [features.multi_agent_v2] wait_agent_enabled = true and

retesting in a fresh codex exec process did not change the behavior; the config was rolled back.

  1. 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.

View original on GitHub ↗

4 Comments

github-actions[bot] contributor · 17 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #37237
  • #36586

Powered by Codex Action

CCanxue · 17 days ago

Same root cause as #36586 / #34833: the task is stored only in encrypted_content and 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 plaintext input_text inside the agent_message item is ignored by DeepSeek (its Responses compatibility table only accepts message, function_call, function_call_output, reasoning, and web_search_call input 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-fix

flyshub · 16 days ago

Reproduced 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:

  • Rollout logs show the child receives Message Type: NEW_TASK ... Payload: followed by an empty content block and <<ENCRYPTED keys=['type','encrypted_content']>> — the plaintext never reaches the child, and no decryption error is logged.
  • Tested spawn_agent (initial message) and followup_task, fork_turns="none" and fork_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.
  • Direction asymmetry confirmed: child FINAL_ANSWER reaches 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.

jdcodes1 · 9 days ago

The "never decrypts/consumes encrypted_content" observation is by design — which is exactly why the failure is silent. InterAgentCommunication::to_model_input_item renders the payload as a plaintext header ("Message Type: NEW_TASK … Payload:\n") followed by an EncryptedContent content 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() vs new_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 an EncryptedContent item ships to a non-OpenAI-backed request — today that's the exact signature of this bug and it's invisible.