Client or integration
Codex App
Area
Catalog / models
Summary
After Codex Desktop self-updated its bundled runtime to codex-cli 0.151.0-alpha.7.1, the Codex app-server started crash-looping within minutes ("ChatGPT hit a snag"). The same OpenCodex 2.33.0 proxy process had been running for 22.8 hours with a completely stable app-server immediately before that update, so the proxy itself is not the new variable — the Codex version is.
The catalog OpenCodex writes to model_catalog_json appears to be built for the pre-0.151 model schema. Three concrete divergences, all verified by diffing OpenCodex's opencodex-catalog.json against the models_cache.json that Codex 0.151 fetched for itself:
1. shell_type disagrees on every native model. Codex 0.151 reports unified_exec; OpenCodex writes shell_command for 10/10 rows in the generated catalog.
| model |
Codex 0.151 models_cache.json |
OpenCodex catalog |
gpt-5.6-sol |
unified_exec |
shell_command |
gpt-5.6-terra |
unified_exec |
shell_command |
gpt-5.6-luna |
unified_exec |
shell_command |
gpt-5.5 |
unified_exec |
shell_command |
gpt-5.4 |
unified_exec |
shell_command |
gpt-5.4-mini |
unified_exec |
shell_command |
gpt-5.3-codex-spark |
unified_exec |
shell_command |
codex-auto-review |
unified_exec |
shell_command |
2. The value is pinned in two places, and one of them is a validator. grep -rn "unified_exec" src/ returns 0 hits in 2.33.0 — the newer value is not known to the codebase at all.
src/codex/catalog/sync.ts:378 hardcodes shell_type: "shell_command" in the entry it builds.
src/codex/catalog/metadata.ts:551 — hasNativeCatalogRowShape() requires entry.shell_type === "shell_command". A row whose genuine value is unified_exec therefore can never satisfy the native-row shape check, so it cannot survive as-is even when upstream data is correct.
3. Four fields that 0.151 emits are never written. Each returns 0 references in src/:
node_repl_disabled
node_repl_auto_review_required
include_plugin_usage_instructions
include_apps_usage_instructions
Since config.toml's model_catalog_json makes Codex consume the OpenCodex catalog instead of its own models_cache.json, the app-server ends up running with the wrong tool-surface definition and without the node_repl / plugin gating flags. This matters more on setups that actually use those features — this machine has node_repl configured as an MCP server and 14 plugins enabled.
Removing that one config line resolves it. ocx stop (which un-injects model_catalog_json and openai_base_url) restored stability immediately; the app has been stable since. Notably the catalog file itself is still on disk — Codex simply stops reading it — which points at the catalog contents rather than at the proxy being in the request path.
Possibly relevant: ocx status reports Codex runtime: ...\npm\codex.cmd, Codex version: 0.146.0, Codex source: configured, while the Desktop app now bundles 0.151.0-alpha.7.1. If the catalog is generated against the pinned CLI version rather than the runtime the app actually launches, that would explain why the generated rows kept the 0.146-era shape. Catalog clamp: inactive.
This looks like the same class of defect as #1408 (OpenCodex injecting a shape that a newer Codex rejects, crashing the Desktop app), one Codex version later.
Reproduction
- Windows 11, OpenCodex 2.33.0, Codex Desktop with bundled codex-cli 0.151.0-alpha.7.1 (app
26.825.5331.0, client 26.825.41651).
ocx start — injects openai_base_url and model_catalog_json into ~/.codex/config.toml.
- Open Codex Desktop and do normal work (several threads,
spawn_agent sub-agents, node_repl MCP server configured, plugins enabled).
- The app-server dies and respawns every few minutes; the app shows "ChatGPT hit a snag".
ocx stop → app-server stays up.
Diff that shows the divergence:
# what Codex 0.151 fetched for itself
jq '.models[] | select(.slug=="gpt-5.6-sol") | {slug, shell_type, node_repl_disabled}' ~/.codex/models_cache.json
# -> "unified_exec", false
# what OpenCodex wrote and pointed Codex at
jq '.models[] | select(.slug=="gpt-5.6-sol") | {slug, shell_type, node_repl_disabled}' ~/.codex/opencodex-catalog.json
# -> "shell_command", null (key absent)
Version
2.33.0
Operating system
Windows 11 Pro (build 26200)
Provider and model
openai / gpt-5.6-sol (native passthrough; also affects terra, luna, and the other native rows)
Logs or error output
# app-server lifetimes from Codex's own diagnostic log DB.
# The proxy (bun, PID 27032) started 08-28 05:03:49 and ran continuously across this whole window.
08-28 00:03:22 -> 08-28 03:04:05 alive 10843s
08-28 03:04:28 -> 08-28 03:37:25 alive 1977s
08-28 05:01:46 -> 08-29 03:51:43 alive 82197s <-- 22.8 h, proxy running the entire time
--------------- 03:56 Codex Desktop self-updates to codex-cli 0.151.0-alpha.7.1 ---------------
08-29 03:52:38 -> 08-29 03:56:12 alive 214s
08-29 03:56:38 -> 08-29 03:57:23 alive 45s
08-29 03:57:38 -> 08-29 04:07:44 alive 606s
08-29 04:23:33 -> 08-29 04:28:41 alive 308s
08-29 04:29:21 -> 08-29 04:34:36 alive 315s
08-29 04:36:09 -> 08-29 04:41:07 alive 298s
08-29 04:41:57 -> 08-29 04:44:17 alive 140s
--------------- 04:41 proxy stopped (model_catalog_json un-injected) -> stable ---------------
# The app-servers stop mid-stream with no panic and no error record, so I could not
# capture an exit code or stack. The correlation above plus the schema diff is the
# evidence I have; I have NOT proven the exact crash instruction.
# Also present on every thread/start and thread/resume (understood to be by design,
# and gated on `websockets: false` — including only in case the churn is relevant):
ERROR codex_api::endpoint::responses_websocket ...
transport="responses_websocket" websocket.warmup=true
failed to connect to websocket: HTTP error: 426 Upgrade Required,
url: ws://127.0.0.1:10100/v1/responses
Redacted configuration
{
"websockets": false,
"defaultProvider": "openai",
"subagentModels": ["gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "deepseek/deepseek-v4-flash"],
"providers": {
"openai": { "modelContextWindows": { "gpt-5.6-sol": 922000 } }
}
}
Relevant ~/.codex/config.toml (injected lines plus the features that the missing catalog fields govern):
model_catalog_json = "C:\Users\[USER]\.codex\opencodex-catalog.json"
openai_base_url = "http://127.0.0.1:10100/v1"
[features]
multi_agent = true
[mcp_servers.node_repl]
command = 'C:\Users\[USER]\AppData\Local\OpenAI\Codex\runtimes\cua_node\...\node_repl.exe'
Suggested fix
- Stop pinning
shell_type to "shell_command" (sync.ts:378) and accept/propagate unified_exec.
- Relax
hasNativeCatalogRowShape() (metadata.ts:551) so both values validate, rather than treating shell_command as the definition of a native row.
- Pass through
node_repl_disabled, node_repl_auto_review_required, include_plugin_usage_instructions, and include_apps_usage_instructions from the upstream model data.
- Consider generating the catalog against the runtime the Desktop app actually launches rather than the
source=configured CLI version, or warn when the two diverge.
Client or integration
Codex App
Area
Catalog / models
Summary
After Codex Desktop self-updated its bundled runtime to codex-cli 0.151.0-alpha.7.1, the Codex app-server started crash-looping within minutes ("ChatGPT hit a snag"). The same OpenCodex 2.33.0 proxy process had been running for 22.8 hours with a completely stable app-server immediately before that update, so the proxy itself is not the new variable — the Codex version is.
The catalog OpenCodex writes to
model_catalog_jsonappears to be built for the pre-0.151 model schema. Three concrete divergences, all verified by diffing OpenCodex'sopencodex-catalog.jsonagainst themodels_cache.jsonthat Codex 0.151 fetched for itself:1.
shell_typedisagrees on every native model. Codex 0.151 reportsunified_exec; OpenCodex writesshell_commandfor 10/10 rows in the generated catalog.models_cache.jsongpt-5.6-solunified_execshell_commandgpt-5.6-terraunified_execshell_commandgpt-5.6-lunaunified_execshell_commandgpt-5.5unified_execshell_commandgpt-5.4unified_execshell_commandgpt-5.4-miniunified_execshell_commandgpt-5.3-codex-sparkunified_execshell_commandcodex-auto-reviewunified_execshell_command2. The value is pinned in two places, and one of them is a validator.
grep -rn "unified_exec" src/returns 0 hits in 2.33.0 — the newer value is not known to the codebase at all.src/codex/catalog/sync.ts:378hardcodesshell_type: "shell_command"in the entry it builds.src/codex/catalog/metadata.ts:551—hasNativeCatalogRowShape()requiresentry.shell_type === "shell_command". A row whose genuine value isunified_exectherefore can never satisfy the native-row shape check, so it cannot survive as-is even when upstream data is correct.3. Four fields that 0.151 emits are never written. Each returns 0 references in
src/:Since
config.toml'smodel_catalog_jsonmakes Codex consume the OpenCodex catalog instead of its ownmodels_cache.json, the app-server ends up running with the wrong tool-surface definition and without thenode_repl/ plugin gating flags. This matters more on setups that actually use those features — this machine hasnode_replconfigured as an MCP server and 14 plugins enabled.Removing that one config line resolves it.
ocx stop(which un-injectsmodel_catalog_jsonandopenai_base_url) restored stability immediately; the app has been stable since. Notably the catalog file itself is still on disk — Codex simply stops reading it — which points at the catalog contents rather than at the proxy being in the request path.Possibly relevant:
ocx statusreportsCodex runtime: ...\npm\codex.cmd,Codex version: 0.146.0,Codex source: configured, while the Desktop app now bundles 0.151.0-alpha.7.1. If the catalog is generated against the pinned CLI version rather than the runtime the app actually launches, that would explain why the generated rows kept the 0.146-era shape.Catalog clamp: inactive.This looks like the same class of defect as #1408 (OpenCodex injecting a shape that a newer Codex rejects, crashing the Desktop app), one Codex version later.
Reproduction
26.825.5331.0, client26.825.41651).ocx start— injectsopenai_base_urlandmodel_catalog_jsoninto~/.codex/config.toml.spawn_agentsub-agents,node_replMCP server configured, plugins enabled).ocx stop→ app-server stays up.Diff that shows the divergence:
Version
2.33.0
Operating system
Windows 11 Pro (build 26200)
Provider and model
openai / gpt-5.6-sol (native passthrough; also affects terra, luna, and the other native rows)
Logs or error output
Redacted configuration
{ "websockets": false, "defaultProvider": "openai", "subagentModels": ["gpt-5.6-luna", "gpt-5.6-sol", "gpt-5.6-terra", "deepseek/deepseek-v4-flash"], "providers": { "openai": { "modelContextWindows": { "gpt-5.6-sol": 922000 } } } }Relevant
~/.codex/config.toml(injected lines plus the features that the missing catalog fields govern):Suggested fix
shell_typeto"shell_command"(sync.ts:378) and accept/propagateunified_exec.hasNativeCatalogRowShape()(metadata.ts:551) so both values validate, rather than treatingshell_commandas the definition of a native row.node_repl_disabled,node_repl_auto_review_required,include_plugin_usage_instructions, andinclude_apps_usage_instructionsfrom the upstream model data.source=configuredCLI version, or warn when the two diverge.