Repository navigation
[Bug] Per-role model_fallback causes Codex 0.146.0 to reject custom agent TOML #1190
Description
Client or integration
Codex CLI and Codex App
Area
Proxy and routing / Catalog and models / Documentation
Summary
OpenCodex documents the per-role model_fallback field in $CODEX_HOME/agents/*.toml as the second source in its spawned-worker fallback priority:
- requested primary model
- the role's
model_fallback - global
subagentModelFallback
However, Codex CLI 0.146.0 strictly deserializes custom-agent TOML files. If a role contains model_fallback, Codex reports it as an unknown field and skips the entire role definition. The role therefore never enters the multi_agent_v1 runtime registry, so OpenCodex cannot apply the documented fallback chain.
This appears to be a compatibility defect between OpenCodex's documented per-role fallback extension and Codex's native custom-agent schema, rather than a provider-specific model failure.
Related feature: #374
Current documentation: https://opencodex.me/guides/sub-agent-surface/#fallback-chains
Reproduction
The failure was reproduced in an isolated temporary CODEX_HOME; the working global configuration was not modified.
- Create
$CODEX_HOME/config.toml:
[features]
multi_agent = true- Create
$CODEX_HOME/agents/test_worker.toml:
name = "test_worker"
description = "Minimal fallback compatibility test"
model = "opencode-go/deepseek-v4-flash"
model_fallback = ["deepseek/deepseek-v4-flash", "gpt-5.6-luna"]
developer_instructions = """
Return a short result.
"""- Run:
$env:CODEX_HOME = "C:\path\to\isolated-codex-home"
codex doctor --all --no-color --ascii-
Observe that Codex loads
config.tomlsuccessfully but skipstest_worker.toml. -
Remove only the
model_fallbackline and restart Codex. -
The role is then registered and appears in the current task's
multi_agent_v1Available roles.
Real configuration impact
The original setup contained five custom roles:
luna_worker.toml: nomodel_fallback; registered successfullydeepseekflash_go_worker.toml: hadmodel_fallback; not registereddeepseekflash_worker.toml: hadmodel_fallback; not registeredglm52_worker.toml: hadmodel_fallback; not registeredkimik3_worker.toml: hadmodel_fallback; not registered
After removing only model_fallback from the four affected files and fully restarting Codex, all five custom roles were present in the live runtime registry:
deepseekflash_go_worker
deepseekflash_worker
glm52_worker
kimik3_worker
luna_worker
Version
- OpenCodex:
2.10.0 - Codex CLI:
0.146.0 - Codex installation: npm package
- Multi-agent mode:
v1 agents.enabled:true
Operating system
Windows 11, build 26200, x86_64
Provider and model
The deserialization failure happens before model routing, so it is not provider-specific.
The affected real-world roles used:
opencode-go/deepseek-v4-flashdeepseek/deepseek-v4-flashopencode-go/glm-5.2opencode-go/kimi-k3- fallback target
gpt-5.6-luna
Logs or error output
Configuration
[!!] config config loaded
config.toml parse ok
startup warnings 1
startup warning Ignoring malformed agent role definition: failed to deserialize agent role file at C:\path\to\isolated-codex-home\agents\test_worker.toml: unknown field `model_fallback`The isolated codex doctor run exited non-zero because the temporary home intentionally contained no authentication credentials. That is unrelated to the agent parsing warning; config.toml parse was ok, and the exact startup warning above was emitted before any model request.
Expected behavior
A per-role fallback mechanism documented by OpenCodex should not invalidate the underlying Codex custom-agent definition.
At minimum, OpenCodex should detect that the installed Codex runtime rejects model_fallback and provide a clear compatibility warning or migrate the fallback metadata elsewhere.
Actual behavior
Codex rejects the complete custom-agent TOML before the role can be registered. From the user's perspective:
- the TOML file exists;
- the configured primary and fallback models both exist;
- the role is nevertheless absent from
multi_agent_v1 Available roles; - spawning with that
agent_typeis rejected as an unregistered role.
Removing the documented fallback field fixes registration, but loses the per-role proxy fallback metadata.
Root-cause analysis
Codex's agent-role TOML schema denies unknown fields. model_fallback is an OpenCodex extension, but it is stored in the same TOML document that Codex must deserialize before exposing the role.
The proxy may be able to read this field independently, but Codex rejects the role first. As a result, the documented fallback feature prevents the role from reaching the spawn surface it is meant to protect.
Suggested fixes
Prefer keeping OpenCodex-only metadata outside files parsed by native Codex. For example:
- Store per-role fallback chains in
~/.opencodex/config.json, keyed by role name or agent TOML path. - Use a separate OpenCodex sidecar metadata file.
- Add a version/schema compatibility check and refuse to configure unsupported per-role TOML fields.
- Provide an
ocx doctordiagnostic that scans$CODEX_HOME/agents/*.tomland warns thatmodel_fallbackwill make affected Codex versions skip the role. - If future Codex versions add a native fallback field, gate direct TOML emission on confirmed schema support.
The global subagentModelFallback mechanism can remain in OpenCodex config because it does not contaminate Codex-owned role TOML.
Workaround
Remove model_fallback from every $CODEX_HOME/agents/*.toml file, restart Codex completely, and define fallback behavior through:
- OpenCodex's global fallback configuration; or
- main-agent routing instructions that explicitly retry a fallback role/model.
Checks
- I searched existing issues and documentation.
- I removed secrets, tokens, account details, request credentials, and personal data.
- The failure was reproduced in an isolated temporary
CODEX_HOME. - Registration was verified again after removing only the unsupported field.
Activity
github-actions commentedon Aug 7, 2026
Automated translation bookkeeping — detected language: English.
fix(subagent): move per-role model fallback into opencodex config (li…
fix(subagent): move per-role model fallback into opencodex config (li…
Ingwannu commentedon Aug 8, 2026
Confirmed: native Codex rejects the OpenCodex-only
model_fallbackkey before the custom role can register. Draft PR #1210 tracks the correct architectural fix by moving per-role fallback metadata into OpenCodex config and retaining a doctor warning/migration path for legacy TOML. The PR author has not marked its own readiness checklist complete and CI remains queued, so this issue stays open until review and merge; removing the unsupported TOML key remains the safe workaround.fix(subagent): move per-role model fallback into opencodex config (#1190
Wibias commentedon Aug 9, 2026
Resolved on
dev.The architectural fix from #1210 has been landed directly rather than merged through the PR.
The landed implementation:
moves supported per-model fallback chains into OpenCodex configuration via
subagentModelFallbackByModel;stops recommending the Codex-incompatible
model_fallbackfield in$CODEX_HOME/agents/*.toml;retains legacy TOML reading only as a compatibility/migration path;
adds
ocx doctordiagnostics for agent TOML files that still containmodel_fallback;preserves the intended fallback order as:
primary → keyed OpenCodex fallback → global fallback → legacy TOML fallbackThe main landed change is
ba5215021, together with the contributor's follow-up doctor/parser commits and corrective precedence commitfc17327b3.PR #1210 was subsequently closed because its implementation had already been landed on
dev.Closing this issue as completed.
fix(subagent): move per-role model fallback into opencodex config (li…