MultiAgentV2 cross-provider subagent cannot consume encrypted task assignment

Open 💬 12 comments Opened Jul 22, 2026 by qqq-jump
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

With an OpenAI parent and a correctly selected non-OpenAI custom-provider child, MultiAgentV2 delivers the child assignment only as encrypted content that the custom-provider model cannot consume.

The spawned child metadata shows the intended custom role, provider, model, and MultiAgentV2 implementation, but the child sees an empty visible Payload: and reports that it has no assignment.

A same-provider OpenAI child consumes an otherwise equivalent encrypted assignment successfully.

Environment

  • Codex CLI: 0.145.0
  • Surface: Codex desktop connected to a remote Codex app-server over SSH
  • Multi-agent version: v2
  • Parent provider: OpenAI
  • Child role: registered custom agent
  • Child provider: non-OpenAI, OpenAI-compatible Chat Completions provider
  • Child model: Kimi K3

Reproduction

  1. Enable multi_agent_v2.
  2. Configure a registered custom child agent using a non-OpenAI provider and an OpenAI-compatible Chat Completions model.
  3. Start an OpenAI-backed parent.
  4. Spawn the custom child with a unique harmless marker and an explicit instruction to run pwd.
  5. Inspect the spawned session metadata and child handoff.

The session metadata confirms:

  • agent_role is the registered custom role.
  • multi_agent_version is v2.
  • model_provider is the intended custom provider.
  • model is the intended custom model.

The stored handoff displays an empty Payload: and contains an encrypted-content block. The child reports that it received no assignment and does not execute the marker or pwd.

In a related continuation path, the parent can terminate with:

Encrypted function output content could not be decrypted or decoded.

Control: same-provider child

Repeat the test with an OpenAI child.

Its stored handoff also displays an empty visible Payload: plus encrypted content, but the OpenAI child successfully consumes the assignment, reproduces the marker, runs pwd, and returns the expected path.

This indicates that general v2 dispatch works and that the problem is specific to the provider boundary.

Control: provider-neutral delivery

As a diagnostic only, provide the same assignment to the custom child through a single-use, permission-restricted, nonce-bound local file referenced by the custom agent's developer instructions.

The custom child then executes the marker and pwd successfully.

This confirms that:

  • The custom provider and model are operational.
  • Child provider/model selection works.
  • The task itself is valid.
  • Failure occurs when the assignment is carried only through the encrypted MultiAgentV2 field.

A fixed file inbox is not a safe permanent workaround because of stale-task, concurrency, cleanup, attribution, and local instruction-injection risks.

Expected behavior

Codex should make the assignment available to the selected child in a representation that its configured provider can consume.

Possible implementations include decrypting/translating the assignment within Codex before invoking a provider that does not support OpenAI encrypted tool parameters, or explicitly rejecting unsupported cross-provider delegation before spawning the child.

Actual behavior

The custom child is spawned with the correct role, provider, and model, but cannot consume the encrypted assignment and behaves as though no task was supplied.

Related issues

  • #33267 - exact decryption error when consuming MultiAgentV2 child results
  • #17541 - provider-specific encrypted content retained across a provider/model boundary
  • #26753 - MultiAgentV2 agent tools use encrypted parameters
  • #27205 - model not configured for encrypted tool use
  • #17598 - native subagent orchestration with non-OpenAI custom providers
  • #32753 - encrypted MultiAgentV2 assignments are no longer observable

Additional notes

This is not a request to support a CPA-backed parent. The failing topology is specifically:

OpenAI parent -> registered non-OpenAI custom-provider child

Please let me know which narrowly scoped logs or sanitized session records would help. I have intentionally omitted authorization data, internal network details, complete encrypted blobs, and unrelated prompts.

View original on GitHub ↗

12 Comments

github-actions[bot] contributor · 1 month ago

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

  • #33551

Powered by Codex Action

qqq-jump · 1 month ago

Thanks — I reviewed #33551. It is closely related, but I do not think it is an exact duplicate.

#33551 focuses on external Responses providers receiving the OpenAI-specific agent_message item type, which may be rejected even when the item is plaintext.

This report reproduces with a custom provider using the OpenAI-compatible Chat Completions protocol. The child session is created with the correct custom role, provider, and model, but the assignment is available only through the encrypted MultiAgentV2 handoff and the child behaves as though no task was supplied. The same encrypted handoff is consumed successfully by an OpenAI child, while the same custom-provider child executes the task when it is delivered through a provider-neutral plaintext diagnostic.

So the reports may share the same broader need for provider-aware inter-agent transport, but they exercise different provider protocols and failure points. I am leaving this open for maintainer triage and am happy for it to be consolidated if the fix for #33551 is intended to cover Chat Completions providers as well.

ignatremizov · 1 month ago

You can change model catalogue to force v1. Anyways duplicate of #28058

ysxk · 1 month ago

Corroboration from Codex desktop multi-role session

Confirmed the same MultiAgentV2 cross-provider failure on Codex desktop / CLI 0.145.0-alpha.30, macOS Darwin 25.5.0 arm64, with project-local agents under .codex/agents/.

Topology

  • Parent: OpenAI gpt-5.6-sol (MultiAgentV2)
  • Child A: registered frontend role → kimi-k3 (custom/non-OpenAI)
  • Child B: registered backend role → gpt-5.6-sol (OpenAI control)
  • Child C: registered skills_openapi role → grok-4.5 via external Responses gateway (separate wire-format failure; see also #33551)

Observed behavior (Kimi K3 child)

  1. Parent spawn_agent(agent_type=frontend, ...) succeeds; child thread starts with correct role/model.
  2. Child history contains:

``
Message Type: NEW_TASK
Task name: /root/frontend_...
Sender: /root
Payload:
`
followed by
encrypted_content only (visible Payload:` empty).

  1. Child immediately replies that no concrete task payload was assigned / parent has not sent a task, then stands by. 0 tool calls.
  2. Parent followup_task to the same child produces the same empty-payload handoff; child reasons "The parent agent hasn't sent a task yet" and stands by again.
  3. Control (same parent, same MultiAgentV2, same encrypted handoff shape): backend child on gpt-5.6-sol consumes the assignment and executes immediately.
  4. Control (provider-neutral plaintext): temporarily embedding the approved task into the frontend role developer_instructions makes the K3 child start working (reads repo). Same model channel is therefore operational; only the encrypted MultiAgentV2 assignment path fails.
  5. Control (solo role start): launching the frontend role outside multi-agent / with normal plaintext user turns also works. Failure is specific to MultiAgentV2 encrypted task delivery, not “K3 is down”.

Follow-up

Parent eventually completed the work by temporarily spawning the same frontend role on gpt-5.6-sol. Persistent project config remained on K3.

Expected

If Codex allows selecting a non-OpenAI provider for a registered child role, MultiAgentV2 should deliver spawn/followup/send_message assignments in a representation that provider can consume (decrypt/translate at the boundary to a standard plaintext message item), or fail fast with an explicit unsupported-cross-provider error before the child stands by forever.

Related

  • #33551 — external Responses providers reject OpenAI-specific agent_message items (matches our Grok path)
  • #28058 — encrypted MultiAgentV2 payloads remove readable audit trail
  • #33267 — encrypted multi-agent function output decrypt failures

Happy to provide redacted rollout excerpts (parent + child) if useful; avoiding full ciphertext and internal network details here.

qqq-jump · 1 month ago

Thanks — V1 can indeed be forced and works as a workaround, but it gives up quite a bit of V2 functionality.

My understanding is that #28058 is related but slightly different: it concerns the loss of a readable audit trail, whereas this issue concerns the encrypted handoff preventing a non-OpenAI sub-agent from receiving the task at all. The underlying mechanism may be the same, but the user-facing problems are different.

CCanxue · 25 days ago

Additional data from codex-cli 0.146.0 source with a real DeepSeek child (wire-captured).

For the non-OpenAI -> non-OpenAI direction, the task text only ever reaches the child inside encrypted_content; DeepSeek drops that block and the child sees an empty Payload:. Even after rewriting the agent_message content so the payload is plaintext input_text, DeepSeek still ignores the agent_message item in most runs. The task is only consumed reliably when delivered as a plain user message.

For the OpenAI -> non-OpenAI direction, message is real ciphertext with encrypted_function_args: null, so a local request transform cannot decrypt it (see also #36376).

We published a local patch that delivers V2 spawn / followup_task / send_message payloads as plain user input for non-OpenAI providers (OpenAI path unchanged), verified end-to-end: https://github.com/CCanxue/codex-deepseek-subagent-fix

YukiagoTpf · 22 days ago

Follow-up after validating the plaintext collaboration changes shipped in 0.147.0-alpha.1 via #35845:

The cross-provider failure described here remains reproducible on a 0.147.0-alpha.4 source baseline.

The alpha.1 change added a valid plaintext receiving path, but that path is entered only when encrypted_function_args == Some([]) and the tool namespace is exactly collaboration. The MultiAgentV2 schemas still unconditionally mark the message fields for spawn_agent, send_message, and followup_task with .with_encrypted(). An OpenAI parent therefore normally supplies actual encrypted arguments, the call remains Direct, and the child assignment is still constructed with InterAgentCommunication::new_encrypted(...).

This leaves the original third-party-provider topology unresolved. It also does not cover custom or absent tool namespaces, does not expose an explicit delivery policy, and does not fail before creating a child that cannot consume the encrypted task.

I implemented and tested a local source-level path with an opt-in plaintext delivery policy, a non-reserved tool namespace, end-to-end call classification, and a fail-closed guard. Targeted feature tests passed 34/34, targeted MultiAgentV2 tests passed 74/74, the release build succeeded, and a restarted Codex Desktop session successfully completed an OpenAI-parent to third-party-provider-child smoke test.

The full analysis, affected source paths, sanitized configuration shape, and validation results are documented in #37197.

CCanxue · 22 days ago

Thanks for the detailed analysis. It matches what we observed on the non-OpenAI parent side: the #35845 plaintext marker is only entered with encrypted_function_args == Some([]), which third-party parents do not emit, and even a plaintext agent_message item is dropped by DeepSeek (its Responses compatibility table only accepts message, function_call, function_call_output, reasoning, and web_search_call item types).

Our local patch takes a simpler route for the non-OpenAI parent case: V2 spawn / followup_task / send_message payloads are delivered as plain UserInput (V1-style standard user messages), verified end-to-end with deepseek-v4-flash. It intentionally does not cover the OpenAI-parent -> third-party-child case, which still needs an opt-in plaintext delivery policy like the one you described; the fail-closed guard and end-to-end call classification sound like the right direction. Patch, wire evidence, and write-up: https://github.com/CCanxue/codex-deepseek-subagent-fix

snoyiatk · 17 days ago

+1 we need to merge/fix this issue so codex is really usable with open-weighted models

NOirBRight · 14 days ago

CodexHub Beta4.1 follow-up (sanitized; no credentials or raw ciphertext included).

This issue remains an upstream producer/delivery limitation for the OpenAI-parent -> non-OpenAI-child direction. We reproduced that the child can be created correctly while the V2 assignment is available only through an agent_message/encrypted_content handoff containing ciphertext. A Gateway downstream of the parent cannot decrypt that value; simply converting the item shape to a normal function/message or removing an Official schema flag does not restore the task body.

CodexHub Beta4.1 has completed the separate Gateway adaptation work: V2 namespace declarations are presented to third-party models as ordinary function tools, aliases are deterministic and reversible, streamed/non-streamed calls and history are adapted, and Official OpenAI traffic remains passthrough. This is an adapter for ordinary tool-calling models, not a claim that they natively understand Codex V2.

The missing piece is provider-aware delivery on the upstream producer side: retain encrypted transport for OpenAI targets, but use a provider-neutral plaintext user/message path for non-OpenAI targets across spawn/follow-up/send-message, with a fail-closed error when unsupported. We are keeping the full external-V2 lifecycle gate open rather than marking it passed based only on tool declarations or a model catalog flag.

ta9to · 12 days ago

Reproduced on stable 0.147.0 with Vercel AI Gateway + DeepSeek

I reproduced the OpenAI-parent -> non-OpenAI-child failure on the current stable CLI, with a Responses-compatible hosted gateway rather than a local provider.

Environment

  • macOS
  • codex-cli 0.147.0
  • Parent: OpenAI gpt-5.6-sol / MultiAgentV2
  • Registered custom child role: deepseek_flash_0731
  • Child provider: Vercel AI Gateway
  • wire_api = "responses"
  • Child model: deepseek/deepseek-v4-flash-0731
  • Spawn used the registered role with fork_turns = "none"

Observed

  1. The child thread was created successfully.
  2. Child session metadata showed the intended registered role and model_provider = "vercel_ai_gateway"; the child turn used the intended DeepSeek model.
  3. The parent-side spawn_agent.message was stored as encrypted content.
  4. The child model-visible input contained its developer instructions plus environment/plugin context, but not the delegated task.
  5. The child responded that it had received no task and asked for the concrete work item.
  6. A follow-up delivery did not reliably restore the missing assignment.

This matches the empty/missing assignment behavior described here: provider/model selection succeeds, but the dynamic V2 handoff is not consumable across the provider boundary.

Controls

  • A direct authenticated request to the same Vercel /v1/responses endpoint with the exact model returned the expected canary.
  • A direct Codex run using the same custom provider/model returned an exact marker successfully.
  • As a practical control/workaround, an OpenAI native relay child received the V2 assignment and invoked the same DeepSeek profile through a normal plaintext codex exec subprocess. DeepSeek then successfully created a minimal Python Hello, World! program, executed it, and verified exact stdout.

That last control confirms that Vercel authentication, the DeepSeek model, Responses transport, tool execution, and file writes are all operational. The failure remains isolated to native MultiAgentV2 cross-provider task delivery.

shleder · 11 days ago

This is a useful encrypted-handoff control/parser case for codex-rescue. Rescue does not claim to decrypt or translate MultiAgentV2 provider-bound task payloads; I’m testing whether it can inspect the persisted parent/child sessions without crashing, inventing a plaintext assignment, or treating an unsupported cross-provider handoff as executed work.

If you still have an affected local parent/child session pair, could you run:

pipx install codex-rescue
codex-rescue sessions
codex-rescue doctor --latest

A healthy/unknown/unsupported result is useful evidence here. Please do not salvage solely to test this provider transport bug; the important invariant is conservative diagnosis and no replay of unknown child work.

Sanitized output + versions/exit codes only—no ciphertext, raw rollouts/SQLite, prompts, provider credentials, or private paths. Repo: https://github.com/shleder/codex-rescue