Repository navigation
Native subagent orchestration does not work correctly with non-OpenAI custom providers #17598
Description
What version of Codex CLI is running?
0.120.0
What subscription do you have?
ChatGPT Pro
Which model were you using?
gpt-5.4
What platform is your computer?
Linux 5.19.0-43-generic x86_64 x86_64, Linux 6.6.87.2-microsoft-standard-WSL2 x86_64 x86_64
What terminal emulator and version are you using (if applicable)?
Windows Terminal using WSL and PowerShell
What issue are you seeing?
In codex-cli 0.120.0, native subagents do not work correctly with a non-OpenAI custom provider.
I observed two related failures:
-
When the parent session uses OpenAI and the child subagent is configured with a non-OpenAI custom provider, the child rollout is created, but the child keeps the parent OpenAI config instead of applying the custom provider config.
-
When the parent session itself uses the non-OpenAI custom provider, native subagent orchestration does not happen at all. No
spawn_agentcall appears in the rollout, no child rollout is created, and the parent answers directly.
OpenAI-only native subagents work correctly in the same environment, so this appears to be specific to native subagents with non-OpenAI custom providers.
What steps can reproduce the bug?
-
Configure a working non-OpenAI custom provider in
~/.codex/config.toml, for example:[model_providers.company_local] name = "Company Local LLM" env_key = "LOCAL_LLM_API_KEY" wire_api = "responses" [profiles.local_main] model_provider = "company_local" model = "code-fast" [profiles.local_fast] model_provider = "company_local" model = "code-fast"
-
Verify that direct execution works:
codex exec -p local_main --skip-git-repo-check --json "Reply with exactly: LOCAL_OK"
- Add a custom subagent config like:
name = "local_llm_worker"
model_provider = "company_local"
model = "code-fast"
model_reasoning_effort = "medium"
sandbox_mode = "read-only"
developer_instructions = """
Use the local LLM provider for read-only code exploration.
"""
- Reproduce failure case 1, OpenAI parent to custom-provider child:
codex --enable multi_agent_v2 exec -p openai_heavy --skip-git-repo-check --json "Use the local_llm_worker subagent for read-only exploration only. If the subagent runs, end with exactly LOCAL_WORKER_OK. If unavailable, end with exactly LOCAL_WORKER_UNAVAILABLE."
- Reproduce failure case 2, custom-provider parent session:
codex --enable multi_agent_v2 exec -p local_main --skip-git-repo-check --json "You must use the local_llm_worker subagent via native subagent spawning, not by answering yourself. Read-only exploration only. End with exactly LOCAL_PARENT_LOCAL_CHILD_OK or LOCAL_PARENT_LOCAL_CHILD_UNAVAILABLE."
- Optionally repeat the same test with another custom-provider parent profile such as local_fast.
What is the expected behavior?
Native subagents should work consistently with non-OpenAI custom providers.
Expected behavior:
-
If a child subagent specifies:
model_provider = "company_local"model = "code-fast"model_reasoning_effort = "medium"
then the spawned child session should reflect those values in its effective config.
-
If the parent session uses a non-OpenAI custom provider, native subagent orchestration should still occur normally:
spawn_agentshould appear in the rollout- a child rollout should be created
- the parent should not answer directly instead of spawning the child
This should behave analogously to OpenAI-only native subagents, which work correctly in the same environment.
Additional information
What works:
-
Direct execution with the custom provider works correctly
-
OpenAI-only native subagents work correctly
-
A custom subagent with:
model_provider = "openai"model = "gpt-5.4-mini"
correctly produces a child rollout with the expected provider/model/effort values
Observed failure details:
-
In the OpenAI parent -> custom-provider child case:
- child rollout is created
- agent identity and developer instructions are applied
- but child config remains on parent OpenAI values:
model_provider = openaiturn_context.model = gpt-5.4collaboration_mode.settings.model = gpt-5.4effort = high
-
In the custom-provider parent case:
- parent starts correctly on
company_local / code-fast - no
spawn_agentcall appears in the rollout - no child rollout file is created
- parent answers directly
- parent starts correctly on
This makes it look like native subagent support is incomplete or broken for non-OpenAI custom providers, both in child config merging and in orchestration from a custom-provider parent.
Related issues:
- Subagent configuration and orchestration #11701
- Subagent ignores active profile/provider and falls back to openai #13204
- Allow per-subagent model/provider/profile selection #14039
- spawn_agent should preserve explicit model overrides for explorer agents #15170
- Sub-agent role top-level reasoning settings are overridden by inherited parent profile #13849
Activity
github-actions commentedon Apr 13, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
jaloveeye commentedon Apr 13, 2026
Thank you for pointing these out.
After reviewing #16548 and #16893, I believe this issue is related, but not an exact duplicate.
My understanding is that those issues are primarily about subagents not respecting a requested model override within Codex/OpenAI model flows, particularly around
explorerandgpt-5.4-mini.In this case, the main problem seems to be slightly different: role-based/native subagents do not appear to inherit or honor the active custom/local provider or profile correctly, and instead fall back away from the configured local provider path.
Because of that, this may be closer to #13204, and possibly related to the broader subagent configuration inheritance / runtime override issues discussed in #15170 and #14039.
I’m happy to close this if maintainers believe it should be consolidated elsewhere, but at the moment it does not look like a clean duplicate of #16548 or #16893.
iqdoctor commentedon Jul 9, 2026
+1
iqdoctor commentedon Jul 9, 2026
Cross-linking the related main regression:
This looks like part of the same local/custom-provider subagent failure family.
niieani commentedon Jul 11, 2026
This also breaks tools like caara, which give codex the ability to run claude code and antigravity as native subagents.
ZhongXinlin commentedon Jul 26, 2026
I can reproduce a related but narrower failure on macOS with a newer build: the custom-provider child is created with the requested provider/model, but the dynamic task payload is not delivered.
Environment
codex-cli 0.146.0-alpha.3.1gpt-5.6-solMiniMax-M3andMiniMax-M2.7-highspeedwire_api = "responses"multi_agent = truemulti_agent_v2 = falseSanitized provider shape:
Preconditions
spawn_agent.model_provider = minimaxand the requested MiniMax role/model./v1/responsesand/v1/chat/completionscanaries both return an exact unique marker.Reproduction
Spawn a fresh MiniMax child with
fork_turns = "none"and a unique marker inmessage:Observed
minimax-restart-canary-20260727-A.019f9f6d-ea86-7a02-b1fb-41fa47971973does not contain the marker.TASK_PAYLOAD_MISSING.followup_taskalso does not deliver the assignment.Control
A fresh default same-provider child received
same-provider-control-20260727-C, echoed the ID, executed the corresponding inline sorting/sum task exactly, and used no tools. Control session:019f9f6f-6b0f-7381-bb8b-b1b4bde2a794.This localizes the current failure to dynamic
spawn_agent.message/followup_task.messagedelivery for the non-OpenAI custom-provider child. Unlike the original report, the child provider/model selection itself is now observable and correct; task delivery is the failing stage.DoNotBugPlz commentedon Aug 21, 2026
Additional macOS regression data point: 0.148 works, 0.149 falls back to
openaiThis matches failure case 1 in the original report, with a version A/B and two different non-OpenAI child providers.
Environment
0.148.0-alpha.150.149.0-alpha.4model_providerand model:grok-4.6claude-opus-5fork_turns = "1"Version A/B from rollout metadata
Under
0.148.0-alpha.15, both children ran successfully from the same long-lived parent thread:After Desktop updated to
0.149.0-alpha.4, the samespawn_agentshape preserved the role and model but overwrote the provider:The children then failed before producing a usable custom-provider turn.
Two observable failure paths
Fresh
0.149.0-alpha.4thread:The same occurs for
claude-opus-5.Long/resumed thread:
Again, the same occurs for
claude-opus-5.Temporarily enabling
multi_agent_v2for one fresh Grok-only reproduction did not change the result; startup prewarm still used the ChatGPT/OpenAI route.Controls
Expected behavior
The custom-agent configuration layer, especially
model_provider, should be applied before startup prewarm and remote compaction choose their transport/auth route. A ChatGPT-authenticated parent should not cause a custom-provider child model ID to be validated against the ChatGPT model entitlement path.This looks like a
0.149.0-alpha.4provider-application-order regression rather than a model entitlement failure.Related: #37858 and #35751.
DoNotBugPlz commentedon Aug 21, 2026
Source trace: the 0.149 behavior is introduced by #39299
I traced the
0.148 -> 0.149change to #39299 (1a6e07a4febcc0ecfa04464f5e95cb47144cd746), merged on 2026-08-18: “Restrict agent roles to bounded configuration overrides.”The PR's stated design is that an agent role may customize model behavior but must not change the provider configuration inherited from its parent session.
The implementation replaces full role config-layer application with a typed
AgentRoleOverridesallowlist. That allowlist includesmodel, reasoning settings, instructions, personality, service tier, and capability reductions, but excludesmodel_provider.The new tests explicitly assert:
They also assert that the projected role layer does not contain
model_provider.This precisely explains the rollout A/B reported above:
The startup-prewarm and remote-compaction entitlement errors are downstream symptoms: the role's external model override is retained, while its provider override is intentionally dropped, so the external model ID is sent through the parent's ChatGPT/OpenAI route.
I did not find an open PR or issue specifically addressing this #39299 cross-provider consequence.
I understand the authority concern behind #39299, and I am not suggesting restoring unrestricted role config overlays. The remaining product gap could be addressed safely by either:
The current behavior silently drops
model_provider, keeps the incompatible model ID, and surfaces a misleading ChatGPT entitlement error. The current custom-agent documentation should also state that provider selection is parent-owned if that is now the intended contract.PR: #39299
palvaleri commentedon Aug 21, 2026
Additional GLM-5.3/ZAI data point: bundled 0.148 works; bundled and stable 0.149 fall back to
openaiI can independently reproduce the same cross-provider regression on macOS with a ChatGPT-authenticated parent and a read-only custom child role:
Rollout A/B
Last observed working bundled runtime:
First observed regressed bundled runtime:
The child then fails before producing a response:
Stable CLI control
I also reproduced this independently with public stable
codex-cli 0.149.0: a ChatGPT/OpenAI parent used native subagent spawning with the configuredglm53role. Startup prewarm retainedmodel=glm-5.3, routed it through the inherited OpenAI/ChatGPT provider, and returned the same 400 error.Provider/model health control
A direct ephemeral read-only
codex execusing the sameglm-5.3model with explicitmodel_provider="ZAI"completed successfully and returned an exact marker. This confirms that the custom provider endpoint, authentication, and model are healthy; the failing boundary is role-to-child provider application.This independently confirms the cross-provider consequence described above for a third external model/provider combination and shows that it affects stable CLI
0.149.0, not only Desktop's bundled alpha build.The behavior is consistent with #39299: the role model override survives while the role provider override is intentionally excluded. At minimum, spawn should fail closed with an explicit cross-provider-role diagnostic instead of sending the external model ID through the parent's ChatGPT entitlement path. A parent-approved provider/profile allowlist would preserve the security boundary while restoring trusted cross-provider roles.
DoNotBugPlz commentedon Aug 22, 2026
Thanks — this is a very useful independent reproduction, especially the stable
0.149.0control. The ZAI/GLM-5.3 result shows that the regression is not specific to the Grok/Claude providers and strengthens the #39299 cross-provider diagnosis.gNikro commentedon Aug 22, 2026
Additional Windows / Ollama-compatible A/B:
0.148.0-alpha.21works,0.149.0-alpha.4inheritsopenaiI can independently reproduce the same cross-provider regression on Windows with a ChatGPT-authenticated parent and two custom child roles: a worker and a read-only explorer.
The roles use a Responses-compatible custom provider backed by an Ollama-compatible local proxy, with model
deepseek-v4-flash:cloud.Last confirmed working runtime
The child completed through the custom provider.
Regressed runtime
With the same global provider definition and unchanged role files:
Both role types then fail before processing the task:
Controls
deepseek-v4-flash:cloud.openaiacross the version boundary.This confirms the
0.148 -> 0.149behavior described above for another platform and for Ollama-based routing. It is also consistent with the bounded role override behavior introduced by #39299: the role's model override survives while itsmodel_provideroverride is discarded.The security goal of keeping provider authority parent-owned makes sense, but the current partial application is unsafe and misleading. At minimum, spawn should fail closed with an explicit cross-provider-role diagnostic. A parent-approved allowlist for trusted user-level providers would preserve the authority boundary without removing mixed OpenAI-parent / local-child workflows.
DoNotBugPlz commentedon Aug 22, 2026
Thanks, this is a useful repro. Seeing the same 0.148 -> 0.149 break on Windows, through an Ollama-compatible provider, and with both worker and explorer roles rules out a lot of setup-specific noise. The controls are clean too. Appreciate you taking the time to document it.
interconnectedMe commentedon Aug 25, 2026
Confirming this regression independently on Linux with custom native subagents.
Regression matrix:
26.818.22352, bundled CLI0.148.0-alpha.21, withfeatures.multi_agent_v2=false: the custom worker completed successfully.26.818.61809, bundled CLI0.149.0-alpha.4.3, using default V1 (multi_agent_v2=false): failed.0.149.0-alpha.4.3build withfeatures.multi_agent_v2=true: failed identically.The custom-agent configuration retained:
pcordon commentedon Aug 25, 2026
Sorry for the noise from the issue I opened earlier and then closed. Didn’t realize this existing issue was the better place to add the finding.
I think #39299 may explain the current OpenAI-parent → custom-provider-child failure.
Before that PR, agent role configs could override
model_provider. Then #39299 changed role handling so the child inherits the parent provider, while fields likemodelcan still be overridden.That creates a bad state where a child role like:
effectively becomes:
So if the parent is using the ChatGPT/OpenAI provider, the child’s custom model name is sent through that inherited provider and fails with:
What makes this especially confusing is that #14039 was closed as completed with an official statement saying:
But 13 days later, #39299 changed the behavior so a child role can no longer override
model_provider.So from a user perspective, the current behavior appears to directly contradict the way #14039 was resolved.
Is cross-provider subagent routing still intended to be supported?
If the provider inheritance in #39299 is intentional for security reasons, could there be an explicit parent-side opt-in or allowlist for child providers instead of removing the capability entirely?
gNikro commentedon Aug 26, 2026
Still reproducible on Desktop 26.820.7780 / CLI 0.150.0-alpha.8
I retested the same two cross-provider custom roles after updating:
Both children were created, but neither reached its task.
Expected effective child configuration:
Observed in both child rollouts:
Both failed with:
This confirms that the role model override still survives while the role
model_provideris discarded and replaced with the parent provider.Could a maintainer clarify the intended contract after #39299?
instead of retaining the external model and producing a misleading
ChatGPT entitlement error?
tracking the regression?
The last confirmed working bundled runtime remains
0.148.0-alpha.21.interconnectedMe commentedon Aug 29, 2026
Still reproducible on IDE 26.825.41651 / CLI 0.151.0-alpha.7.1
I independently retested this on Linux using the newest marketplace Codex IDE extension in an isolated VS Code extension directory. The active pinned IDE profile was not changed.
Environment:
26.825.41651codex-cli 0.151.0-alpha.7.1gpt-5.6-solglm-52-ollama-workerglm-5.2ollama_cloud_responsesresponsescodex exec --ephemeral --enable multi_agent --disable multi_agent_v2The role was resolved and the child retained
model=glm-5.2, but its configured provider was not used. Startup prewarm went through the ChatGPT/OpenAI backend and failed with:This is the same model-retained/provider-inherited failure previously observed on
0.149. It remains present in the newer0.151.0-alpha.7.1bundled runtime with V1 explicitly selected.The equivalent V2 probe encountered the separate ephemeral root-thread registration failure tracked in #41474.
DoNotBugPlz commentedon Aug 29, 2026
Thanks for retesting this on 0.151.0-alpha.7.1. The explicit V1 run is especially useful: the child still keeps the custom model while inheriting the OpenAI provider, so the regression is still present beyond the 0.150 builds. Good call tracking the V2 ephemeral root-thread problem separately in #41474.