Sub-agent task messages are delivered with an empty payload (Codex Desktop)
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 theNEW_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(alsocodex-command-runner-0.146.0-alpha.9.2) - OS: Windows (PowerShell shell), timezone Asia/Shanghai
- Model provider: custom
deepseekprovider (Responses wire API), modeldeepseek-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
- In any thread, call
spawn_agentwithfork_turns = "none"and amessagethat
contains a unique token and asks the agent to reply with that exact sentence, e.g.:
VERIFY-KAPPA-9944 收到,ping_kappa 在线,消息通道正常。 (any language works).
- Call
wait_agentuntil the sub-agent completes, then inspect its final answer
(e.g. via list_agents).
- Expected: the sub-agent replies with the exact sentence containing the token.
- 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 fileC:\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 fileC:\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, targetcodex_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 hashas_user_event = 0 and first_user_message equal to:
fork_turns = "none": empty stringfork_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_test → smoke_test_agent → convo_test → agent_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.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Reproduced on CLI 0.146.0 (not just Desktop) with deepseek-v4-flash: the child's
agent_messagecontains only theNEW_TASKenvelope with an emptyPayload:and the actual task text inencrypted_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
UserInputdelivery for non-OpenAI providers, OpenAI path unchanged) resolves it; verification and patch here: https://github.com/CCanxue/codex-deepseek-subagent-fixRoot 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:
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.