Repository navigation
[Bug]: Routed models are loaded by Codex app-server but missing from Desktop model picker #241
Description
Summary
OpenCodex successfully injects 13 routed models into the Codex catalog, and the Codex CLI/app-server can read all of them, but Codex Desktop does not show any routed model in its model picker.
The desktop picker only shows the current native models:
- 5.6 Sol
- 5.6 Terra
- 5.6 Luna
- 5.5
- 5.4
- 5.4 Mini
Expected: routed entries such as input/glm-5.2, input/grok-4.5, and input/kimi-k2.7-code should also appear, as described in the OpenCodex “Codex App model picker” documentation.
This does not appear to be a stale catalog, failed injection, or stopped proxy:
- OpenCodex is healthy and running.
model_catalog_jsonandopenai_base_urlare present as root settings.opencodex-catalog.jsoncontains all 13 routed entries withvisibility: "list".- The Codex Desktop bundled CLI's
codex debug modelsreads all 13 routed entries. - A direct
model/listrequest to the bundled Codex app-server also returns all routed entries. - Fully quitting and reopening Codex Desktop does not change the picker.
Reproduction
-
Configure a custom OpenAI Responses-compatible provider:
{ "defaultProvider": "openai", "providers": { "openai": { "adapter": "openai-responses", "baseUrl": "https://chatgpt.com/backend-api/codex", "authMode": "forward" }, "input": { "adapter": "openai-responses", "baseUrl": "https://example.invalid", "authMode": "key" } } } -
Run
ocx start. -
Confirm that
~/.codex/config.tomlcontains:model_catalog_json = "/Users/example/.codex/opencodex-catalog.json" openai_base_url = "http://127.0.0.1:10100/v1"
-
Confirm that the generated catalog contains routed models with
visibility: "list". -
Run the Codex binary bundled with the desktop app:
/Applications/ChatGPT.app/Contents/Resources/codex debug models
Observe that the returned model list includes all routed
input/...entries. -
Fully quit and reopen Codex Desktop.
-
Open the model picker.
-
Observe that only native OpenAI models are displayed; none of the routed
input/...models appear.
Logs and screenshots
$ ocx status
Proxy: running
Health: http://127.0.0.1:10100/healthz ok v2.7.31
$ /Applications/ChatGPT.app/Contents/Resources/codex --version
codex-cli 0.145.0-alpha.27
$ jq -r '.models[] | select(.slug | startswith("input/")) | [.slug, .visibility] | @tsv' ~/.codex/opencodex-catalog.json
input/grok-4.5 list
input/gpt-5.6-sol list
input/glm-5.2 list
input/codex-auto-review list
input/gemma-4 list
input/glm-4.7-flash list
input/gpt-5.3-codex-spark list
input/gpt-5.4 list
input/gpt-5.4-mini list
input/gpt-5.5 list
input/gpt-5.6-luna list
input/gpt-5.6-terra list
input/kimi-k2.7-code listAdditional diagnostic evidence:
- The bundled Codex app-server returns 20 models from
model/list, including all 13 routed entries. - The routed entries are returned as visible/non-hidden.
- Inspection of the current Desktop frontend bundle shows that the picker can switch from catalog visibility to an
available_modelsallowlist when the remoteuse_hidden_modelssetting is active. In this environment, that allowlist appears to contain only native model ids. This would explain why the app-server sees the routed entries while the picker drops them.
Screenshot available if needed: the picker contains only 5.6 Sol, 5.6 Terra, 5.6 Luna, 5.5, 5.4, and 5.4 Mini.
Area
Other
Version
OpenCodex 2.7.31
Codex Desktop 26.715.70719 (build 5650)
Bundled codex-cli 0.145.0-alpha.27
OS
macOS 27.0 (build 26A5378n), Apple Silicon
Config shape
{
"defaultProvider": "openai",
"providers": {
"openai": {
"adapter": "openai-responses",
"baseUrl": "https://chatgpt.com/backend-api/codex",
"authMode": "forward"
},
"input": {
"adapter": "openai-responses",
"baseUrl": "<redacted relay URL>",
"authMode": "key"
}
}
}Checks
- I searched existing issues and docs first.
- I removed secrets, tokens, and personal data from logs and screenshots.
Activity
Wibias commentedon Jul 22, 2026
Thanks for the thorough diagnostic work here - this is clearly not user error.
Your evidence is conclusive: OpenCodex is doing everything correctly on its side. The catalog contains all 13 routed models with
visibility: "list", the app-server returns them viamodel/list, and the bundled CLI reads them all. The injection pipeline is working as designed.The filtering you identified is happening inside the Codex Desktop frontend. When the remote
use_hidden_modelssetting is active, the picker switches from catalog visibility to anavailable_modelsallowlist that only contains native OpenAI model IDs. That allowlist is controlled by the Desktop app's own remote configuration, not by anything OpenCodex writes to the catalog or config.Unfortunately this is outside OpenCodex's control. The Desktop frontend applies its own allowlist on top of whatever the app-server reports, and there's no hook in the catalog format or config.toml to override it.
A couple of things worth trying in the meantime:
use_hidden_modelsremote setting can be toggled off locally (it may be stored in the Desktop app's preferences/state DB under~/Library/Application Support/ChatGPT/on macOS).codexin terminal) does not apply this allowlist, so routed models work there as expected. If the Desktop picker is the only blocker, the CLI remains a fully functional path.lidge-jun commentedon Jul 22, 2026
Status update after investigation: the missing entries are caused by Codex Desktop's remote model allowlist, which filters what the picker shows on the client side. OpenCodex correctly advertises the routed models through the app-server (as your logs show — they are loaded), but the Desktop picker only renders models on its own allowlist. This is outside what the proxy can control.
Keeping this open as an upstream-tracking issue so others hitting the same behavior can find it. If Desktop exposes a supported control for this allowlist, we can reassess whether any OpenCodex-side change is needed.
lidge-jun commentedon Jul 23, 2026
Periodic status check (2026-07-24): unchanged, still upstream-blocked.
OpenCodex catalog generation and app-server delivery continue to work (routed models are loaded by the Codex app-server), but Codex Desktop filters its model picker against a remote
available_modelsallowlist that the proxy cannot influence. No supported proxy-side override exists.Keeping open for upstream tracking; will update when the Desktop picker behavior changes.
docs(devlog): record owner decision ledger for open issues and PRs
Killin-7 commentedon Aug 1, 2026
github-actions commentedon Aug 1, 2026
Automated translation bookkeeping — detected language: unknown.
lidge-jun commentedon Aug 2, 2026
Triage: the proxy side is verified correct — routed
visibility: "list"catalog entries are served (tests/api-catalog-route.test.ts:39). The models missing from the Desktop picker are filtered by the Desktop app's own remote allowlist, which is outside this repository. Leaving open as an upstream/documentation item.lidge-jun commentedon Aug 3, 2026
Re-checked on current
dev. The proxy side does what you would want; the remaining filter is not in this repository.Routed entries are produced with
visibility: "list"(src/codex/catalog/sync.ts:175-202), and the rootmodel_catalog_jsonkey is written into the Codex config atsrc/codex/inject.ts:430-457. That is why app-server loads them — the catalog reaches it intact.Desktop's model picker then applies its own remote
available_modelsallowlist, which lives in the Desktop client and has no equivalent here. There is no proxy-side change that puts an entry into that list.Keeping this open as an upstream tracker rather than closing it: the symptom is real and users hit it, and if Desktop's filtering changes we want the record. But I do not want to leave the impression that a fix is pending on our side, because none is possible from here.
Yuxin-Qiao commentedon Aug 4, 2026
Triage update: the upstream bug behind this Desktop-side filter now has a linked ticket.
model/list, but the Desktop renderer drops them via its own allowlist. Same symptom and root cause as this issue./modeldoes not list models that are reachable via-m.No proxy-side change can put an entry into that allowlist, so this stays upstream-tracked. A docs note describing the limitation and the workarounds (set
model = "<provider>/<model>"directly in~/.codex/config.toml, or use Codex CLI/TUI, which do not apply the allowlist) is being added tocodex-app-models.md.]docs(devlog): triage every open bug issue and PR against dev
lidge-jun commentedon Aug 9, 2026
Fixed on
devas c75e68e (#1244, @Wibias).Closing this manually and stating the chain, since it is inferred rather than linked: #1244 does not reference this issue directly — its body says it supersedes #1056, and #1056 is what #241's timeline actually cross-references. So the path is #241 → #1056 → #1244, with the second hop from prose rather than a GitHub link.
If the picker behaviour you originally reported is not what you see after this ships, reopen and I will treat the chain as broken rather than the fix.
docs(devlog): record WP19, the merges that arrived after the campaign…
docs(devlog): triage every open bug issue and PR against dev
docs(codex-app-models): document Desktop remote allowlist limitation
docs(devlog): record WP19, the merges that arrived after the campaign…
wzp100 commentedon Sep 24, 2026
Resolved Windows case: missing routed models because config injection was skipped (different from the original #241 cause)
Sharing a related symptom with a different root cause for troubleshooting. In #241, the app-server already exposes routed models and only the Desktop picker filters them. In this case, OpenCodex generated the catalog but did not inject the Codex configuration, so a Desktop allowlist diagnosis would have been premature.
Environment: Windows; Codex bundled runtime
0.155.0-alpha.9.2;@bitkyc08/opencodex2.59.0. Native Codex account login remained in use.Before the fix
ocx status: proxy healthy, butrouting=unknown.ocx syncreported+ 4 models appended to Codex catalog, then:config.tomlhad nomodel_catalog_jsonoropenai_base_url. Acodex debug modelskeyword check showed no matching third-party models.requires_openai_authdid not make its ID the built-inopenaiprovider. The external-provider guard correctly avoided overwriting this configuration.Resolution confirmed by the user
config.toml.model_provider = "custom"(or selectmodel_provider = "openai") only if the intended setup is to route the built-in OpenAI provider via OpenCodex. Keep the existing[model_providers.*]definitions.ocx syncand restart Codex/app-server processes if needed.model_catalog_jsonandopenai_base_url = "http://127.0.0.1:10100/v1".Both keys appeared after the change, and the user confirmed that their missing-model problem was resolved without reinstalling the proxy or logging out of the native account. No direct
model/listcomparison was collected, so this case should not be treated as evidence against the Desktop allowlist issue reported in #241.Suggested troubleshooting note: when
ocx syncsaysExternal provider owns config.toml, inspect the active top-levelmodel_providerand the injected root keys before investigating the Desktop picker allowlist. This guard is intentional; users who deliberately need a separate custom provider should preserve that routing choice.All examples above are sanitized; no tokens, credentials, account IDs, real home-directory paths, private URLs, screenshots, or unredacted logs are included.