Sub-agent task messages are delivered with an empty payload (Codex Desktop)

Open 💬 3 comments Opened Aug 1, 2026 by Luh2233
💡 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)?

0.146.0-alpha.9.2

What subscription do you have?

In Codex Desktop on Windows, messages sent to sub-agents via the collaboration tools (spawn_agent initial message, and followup_task messages) never reach the sub-agent. The sub-agent is created, woken, runs a full turn, and completes normally, but the NEW_TASK envelope it receives contains an empty Payload. The sub-agent therefore responds with generic "no task received" text. The reverse direction works correctly: sub-agent final answers (FINAL_ANSWER) are delivered back to the parent thread. This blocks every multi-agent workflow (for example Writer/Checker loop-engineering skills), because spawned agents can never receive their task instructions.

What platform is your computer?

Environment - Product: Codex Desktop (ChatGPT desktop app for Windows, MSIX from Microsoft Store) - Package: OpenAI.Codex_26.727.6591.0_x64__2p2nqsd0c76g0 - Engine: codex-cli 0.146.0-alpha.9.2 (also codex-command-runner-0.146.0-alpha.9.2) - OS: Windows (PowerShell shell), timezone Asia/Shanghai - Model provider: custom deepseek provider (Responses wire API), model deepseek-v4-flash, model_reasoning_effort = "max" - Reproduced on: 2026-08-01 (multiple threads, before and after an app restart and an update attempt; installed version did not change)

What issue are you seeing?

Bug Report: Sub-agent task messages are delivered with an empty payload (Codex Desktop)

Summary

In Codex Desktop on Windows, messages sent to sub-agents via the collaboration tools
(spawn_agent initial message, and followup_task messages) never reach the sub-agent.
The sub-agent is created, woken, runs a full turn, and completes normally, but the
NEW_TASK envelope it receives contains an empty Payload. The sub-agent therefore
responds with generic "no task received" text. The reverse direction works correctly:
sub-agent final answers (FINAL_ANSWER) are delivered back to the parent thread.

This blocks every multi-agent workflow (for example Writer/Checker loop-engineering
skills), because spawned agents can never receive their task instructions.

Environment

  • Product: Codex Desktop (ChatGPT desktop app for Windows, MSIX from Microsoft Store)
  • Package: OpenAI.Codex_26.727.6591.0_x64__2p2nqsd0c76g0
  • Engine: codex-cli 0.146.0-alpha.9.2 (also codex-command-runner-0.146.0-alpha.9.2)
  • OS: Windows (PowerShell shell), timezone Asia/Shanghai
  • Model provider: custom deepseek provider (Responses wire API), model deepseek-v4-flash,

model_reasoning_effort = "max"

  • Reproduced on: 2026-08-01 (multiple threads, before and after an app restart and an

update attempt; installed version did not change)

What steps can reproduce the bug?

Steps to reproduce

  1. In any thread, call spawn_agent with fork_turns = "none" and a message that

contains a unique token and asks the agent to reply with that exact sentence, e.g.:
VERIFY-KAPPA-9944 收到,ping_kappa 在线,消息通道正常。 (any language works).

  1. Call wait_agent until the sub-agent completes, then inspect its final answer

(e.g. via list_agents).

  1. Expected: the sub-agent replies with the exact sentence containing the token.
  2. Actual: the sub-agent replies that it received no request, e.g.

"I don't see a request in your message — it came through empty." The token never
appears in any sub-agent reply.

Repeat the same test with followup_task (with a second unique token) on the same
agent: the agent wakes and completes another turn, but again replies generically
("I'm ready when you are…") and the token is absent.

Repeat with fork_turns = "all": the agent inherits the parent thread history and
may echo or act on old parent messages (it is seeded with a historical user
message instead of the spawn message), but it still never sees the spawn message;
the unique token never appears.

What is the expected behavior?

Root-cause evidence

1. The spawn call is recorded correctly on the parent side

Parent session file
C:\Users\Lenovo\.codex\sessions\2026\08\01\rollout-2026-08-01T22-40-01-019fbdc4-86b0-7350-87b5-5e660a485948.jsonl
contains the spawn_agent function_call with the full message in arguments
(e.g. token VERIFY-4721-OMEGA), and the tool returns {"task_name":"/root/ping_verify"}.
The call itself succeeds.

2. The child thread receives an empty NEW_TASK payload

Child session file
C:\Users\Lenovo\.codex\sessions\2026\08\01\rollout-2026-08-01T23-17-37-019fbde6-f384-7bc3-92f7-2aa242751442.jsonl
(thread of /root/ping_retest) contains:

Message Type: NEW_TASK
Task name: /root/ping_retest
Sender: /root
Payload:

The Payload is empty (appears on both the initial spawn and the followup_task turn).
A grep for the token across the whole child session finds nothing. The child's own
reasoning confirms it: *"The user's message appears to be empty or just the environment
context."*

3. The app log shows the message text was placed in encrypted_content while content is empty

App log database C:\Users\Lenovo\.codex\logs_2.sqlite (table logs, target
codex_core::session::handlers) shows the inter-agent communication submission:

Submission sub=Submission { id: "...", op: InterAgentCommunication { communication:
InterAgentCommunication { id: None, author: AgentPath("/root"),
recipient: AgentPath("/root/ping_clean"), other_recipients: [],
content: "", encrypted_content: Some("这是一条独立的连通性测试指令…") } } }

The full message text sits in encrypted_content; the plaintext content field is
empty. The child-side reader apparently uses content, so the payload is lost.
Out of 58 InterAgentCommunication log rows, 40 have empty content (all
parent→child directions); the 18 non-empty rows are all child→parent FINAL_ANSWER
envelopes, which confirms only the parent→child direction is affected.

4. The child thread is seeded with the wrong initial user message

In C:\Users\Lenovo\.codex\state_5.sqlite (table threads), every sub-agent thread has
has_user_event = 0 and first_user_message equal to:

  • fork_turns = "none": empty string
  • fork_turns = "1": the parent thread's last user message (e.g. "好,你试试")
  • fork_turns = "all": the parent thread's first user message (e.g. the thread's

opening message about inspecting a skill)

It is never set to the spawn message. This is why fork_turns="all" sub-agents
appear to "guess" tasks from stale history: they are literally seeded with a
historical message, not with the task they were spawned for.

Additional information

Additional observations

  • Sub-agents can still run tools. Despite receiving no task, a sub-agent spawned

a nested chain of its own (observed up to 5 levels deep: ping_agent
connectivity_testsmoke_test_agentconvo_testagent_smoke_test),
because it improvised its own interpretation of inherited context. Tool-level
prohibitions in the message (e.g. "do not spawn sub-agents") cannot be enforced
because the message never reaches the agent.

  • Restart / new thread / update attempt do not fix it. The behavior reproduced

across multiple threads, before and after an app restart, and after a Microsoft
Store update attempt (the installed version remained 26.727.6591.0, engine
0.146.0-alpha.9.2; the Store reported no newer version). codex update fails
with "Could not detect the Codex installation method" for this managed install.

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 26 days ago

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

  • #36387
  • #36321
  • #36376

Powered by Codex Action

CCanxue · 25 days ago

Reproduced on CLI 0.146.0 (not just Desktop) with deepseek-v4-flash: the child's agent_message contains only the NEW_TASK envelope with an empty Payload: and the actual task text in encrypted_content, which DeepSeek does not consume. The child initializes and replies that no task was received.

Since Desktop bundles the CLI, patching the bundled binary with the same fix applies to both surfaces. Our local patch (plain UserInput delivery for non-OpenAI providers, OpenAI path unchanged) resolves it; verification and patch here: https://github.com/CCanxue/codex-deepseek-subagent-fix

TOV1C · 16 days ago

Root cause
MultiAgentV2 delivers tasks through InterAgentCommunication: the plaintext content is empty, and the entire task text is placed in the encrypted_content content block. OpenAI endpoints decrypt and render this block server-side, which is why native models work; DeepSeek's Responses implementation does not recognize encrypted_content (community packet captures show that sending a request containing this content item directly returns a 400 / it gets dropped), so the sub-agent only sees an empty Payload:. This is the same family of issues as openai/codex #36493, #36321, #36586, #37237, and #37822.
Verified workaround (currently in effect on this machine)
Modify both entries in ~/.codex/models.json:

  • "multi_agent_version": "v2"
  • "multi_agent_version": "v1"
  • "supports_search_tool": true
  • "supports_search_tool": false

Rationale: supports_search_tool=false makes search_tool_enabled=false, so deferred tools are no longer hidden behind tool_search but are exposed directly to the model (the same mechanism as the workaround in #36382). The v1 tool family then becomes directly visible, and v1 delivers tasks as plain user messages (UserInput), which DeepSeek consumes reliably.