[App] API-key custom providers skip remote model refresh, hiding GPT-5.6 from the picker
What version of the Codex App are you using (From “About Codex” dialog)?
Latest public Codex App releases available on 2026-07-10, independently reproduced on Windows and macOS. Both affected users confirmed that no App update was available. I do not have their exact About-dialog build numbers; the related CLI diagnostics below were captured with codex-cli 0.144.1.
What subscription do you have?
API-key authentication against an OpenAI-compatible custom provider. The same affected users also have ChatGPT accounts, and GPT-5.6 appears normally in the App picker when they use the official ChatGPT provider.
What platform is your computer?
Independently reproduced in Codex App on Windows and macOS. The CLI diagnostics were captured on Fedora Linux x86_64.
What issue are you seeing?
Codex App does not show GPT-5.6 models in the model picker when an API-key-authenticated custom provider is selected, even though all of the following are true:
- The provider's Responses API can successfully run
gpt-5.6-solwhen the model is configured explicitly. GET {base_url}/models?client_version=0.144.1returns HTTP 200 with a valid Codex models manifest containinggpt-5.6-sol,gpt-5.6-terra, andgpt-5.6-lunaas visible/listed models.- The same App installations show the GPT-5.6 family when using official ChatGPT authentication.
- Codex CLI 0.144.1 can use
gpt-5.6-solwith the same custom provider and API key.
With the custom provider selected, affected App users only see models through GPT-5.5. This makes inference availability and picker availability disagree: the model works when named explicitly, but cannot be discovered or selected in the App UI.
This appears to involve two client-side catalog boundaries: the core model refresh gate for API-key custom providers, and possibly the Desktop renderer's additional model filtering.
What steps can reproduce the bug?
- Sign in to Codex with API-key auth.
- Configure a Responses-compatible custom provider:
```toml
model = "gpt-5.6-sol"
model_provider = "gateway"
[model_providers.gateway]
name = "Gateway"
base_url = "https://gateway.example.com/v1"
wire_api = "responses"
requires_openai_auth = true
```
- Have the provider return a valid Codex manifest from
GET /v1/models?client_version=<version>, including visible entries such as:
``json``
{
"models": [
{ "slug": "gpt-5.6-sol", "visibility": "list" },
{ "slug": "gpt-5.6-terra", "visibility": "list" },
{ "slug": "gpt-5.6-luna", "visibility": "list" }
]
}
(Other required ModelInfo fields are omitted here for brevity; the tested endpoint returns the complete upstream manifest.)
- Fully restart Codex App and open the model picker.
- Observe that the GPT-5.6 entries are absent under the custom provider.
- Set
model = "gpt-5.6-sol"directly, or invoke the same provider from Codex CLI, and observe that the model request succeeds. - Switch the App back to official ChatGPT authentication and observe that the GPT-5.6 entries appear in the picker.
No credentials, account IDs, or private gateway URLs are required for the reproduction.
What is the expected behavior?
For an authenticated custom provider, Codex should refresh the provider-owned /models endpoint and expose visible models from the effective catalog in the App picker.
At minimum:
- API-key auth should not prevent an otherwise authenticated custom provider from refreshing its remote model catalog.
- The Desktop picker should not remove provider-returned visible models solely because they are absent from a first-party ChatGPT rollout/allowlist.
- A model that is usable and configured as the current model should be shown by its real slug instead of being absent or reduced to
Custom.
Additional information
Direct endpoint verification
The tested gateway returned HTTP 200 from both supported route shapes, with all three GPT-5.6 slugs:
/v1/models?client_version=0.144.1
/backend-api/codex/models?client_version=0.144.1
gpt-5.6-luna
gpt-5.6-sol
gpt-5.6-terra
CLI catalog diagnostic
On codex-cli 0.144.1 with an API-key custom provider:
codex debug models -> 8 models, including all three GPT-5.6 variants
codex debug models --bundled -> 8 models, including all three GPT-5.6 variants
effective catalog == bundled catalog
This explains why the CLI can appear healthy even when the provider catalog is not refreshed: GPT-5.6 is already present in the 0.144.1 bundled catalog.
Current source path
On current main (4ba28150146e8ae8e949a07951639a929f5ddeae), refresh_available_models returns before fetching unless should_refresh_models() succeeds:
The refresh predicate is currently:
self.endpoint_client.uses_codex_backend().await
|| self.endpoint_client.has_command_auth()
A normal API-key custom provider satisfies neither branch, even when it has valid auth and a working /models endpoint. This is consistent with the earlier API-key catalog report in #15843.
There may also be a second Desktop-only filter after app-server model/list, as described in #19694. The generic custom-provider picker gap is tracked in #10867. This report is narrower: current API-key custom providers with a valid remote Codex manifest cannot make newly available models such as GPT-5.6 appear in the App picker, while explicit model use succeeds.
The documented custom-provider configuration is here: https://developers.openai.com/codex/config-advanced/#custom-model-providers
Suggested regression coverage:
- Configure a custom provider with API-key auth and a mock
/modelsresponse. - Assert that an online refresh reaches that endpoint and updates app-server
model/list. - Assert that a visible provider model is retained by the Desktop picker.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Thanks — I reviewed the suggested issues and believe this report is distinct:
model/listalready contains GPT-5.6.The closest related report is #15843, but #32119 adds a current
0.144.1reproduction for a custom provider whose authenticated/modelsendpoint returns a complete Codex manifest, plus the Codex App picker behavior. The currentshould_refresh_models()predicate still excludes ordinary API-key custom providers.The affected Windows and macOS users confirmed that they were running the latest Codex App releases available to them and that no update was offered. Their exact About-dialog build numbers are not available, so I have intentionally not guessed them.
I’ll keep this open unless a maintainer prefers consolidating it into #15843.
Confirmed on a concrete Windows installation:
26.707.3748.00.144.0-alpha.410.0.26200x64requires_openai_auth = falsegpt-5.6-solObserved behavior:
model/listresponse contains seven visible models, includinggpt-5.6-sol,gpt-5.6-terra, andgpt-5.6-luna.Custom.thread/start+turn/startthrough the exact bundled app-server withmodelProviderset to the custom provider, modelgpt-5.6-sol, and effortxhighcompleted successfully. The provider loggedPOST /v1/responses 200forgpt-5.6-sol.model/listcompleting successfully, so the remaining omission occurs after app-server model resolution, in the Desktop picker/filtering path.The provider used here also exposes the standard OpenAI
{ object, data }model-list shape while Codex's remote catalog expects{ models }; that is a separate compatibility issue. Importantly, after that remote refresh fails, the app-server's effective fallback catalog still contains all three GPT-5.6 variants, yet Desktop filters them out. This independently confirms the Desktop-side filtering described in this report and #19694.Confirmed my side as well.
Seems to be also on K12 Teacher Workspaces
The comment is sent by an agent, behalf of @Menci.
Your two-boundary analysis matches exactly what I see; here's a length-preserving byte-level shim for boundary #2 (the Statsig whitelist filter) plus concrete function/offset locations for a real fix.
Filter location (Codex/ChatGPT.app
26.707.31428,com.openai.codex):webview/assets/app-initial~app-main~onboarding-page~...~k0ede4gb-C17KDkOa.js:$v(e)— zod-parsesuse_hidden_models,available_models,default_modeloff the Statsig dynamic-config payloaday()— readseee('107580212').valueJv({authMethod:e, availableModels:t, models:a, useHiddenModels:o})— the picker filter:``
js
``let l = o && e !== 'amazonBedrock';
a.forEach(n => { if (l ? t.has(n.model) : !n.hidden) { /* keep */ } });
Verify live (paste into DevTools console once you have one on the app):
For any non-ChatGPT-authed session (API-key, Azure, custom OpenAI-compatible) the whitelist branch runs and every
hidden:falsemodel thatapp-server model/listreturned —gpt-5.6-{sol,terra,luna}included — gets stripped, even though the CLI running from the same bundle can invoke them fine.One-byte shim (per-install; gets wiped by Sparkle):
Renames the string literal inside
$v()sosafeParse(e.use_hidden_models)misses and the field defaults tofalse. Length-preserving (asar header untouched), idempotent, reversible. Works becauseEnableEmbeddedAsarIntegrityValidationfuse is OFF on shipped builds.Fix at the source — any one of these:
Jv/ive: skip the whitelist branch whenauthMethod !== 'chatgpt'. Custom API-key providers shouldn't be gated by a ChatGPT-account-scoped rollout list.Jv/ive: unionavailableModelswithmodels.filter(m => !m.hidden)before thet.has()check, so provider-returned visible models can never be dropped.107580212targeting.Happy to help verify a fix if useful.