Skip to content

[Bug][Windows][Codex App] Generated catalog keeps the pre-0.151 schema: shell_type pinned to shell_command, four 0.151 fields never emitted #2896

Description

@c040340

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:551hasNativeCatalogRowShape() 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

  1. 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).
  2. ocx start — injects openai_base_url and model_catalog_json into ~/.codex/config.toml.
  3. Open Codex Desktop and do normal work (several threads, spawn_agent sub-agents, node_repl MCP server configured, plugins enabled).
  4. The app-server dies and respawns every few minutes; the app shows "ChatGPT hit a snag".
  5. 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

  1. Stop pinning shell_type to "shell_command" (sync.ts:378) and accept/propagate unified_exec.
  2. Relax hasNativeCatalogRowShape() (metadata.ts:551) so both values validate, rather than treating shell_command as the definition of a native row.
  3. Pass through node_repl_disabled, node_repl_auto_review_required, include_plugin_usage_instructions, and include_apps_usage_instructions from the upstream model data.
  4. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcatalogModel catalog, slugs, visibility, routed entriesplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)toolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions