[App] API-key custom providers skip remote model refresh, hiding GPT-5.6 from the picker

Resolved 💬 6 comments Opened Jul 10, 2026 by chenty2333 Closed Jul 11, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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-sol when the model is configured explicitly.
  • GET {base_url}/models?client_version=0.144.1 returns HTTP 200 with a valid Codex models manifest containing gpt-5.6-sol, gpt-5.6-terra, and gpt-5.6-luna as 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-sol with 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?

  1. Sign in to Codex with API-key auth.
  2. 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
```

  1. 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.)

  1. Fully restart Codex App and open the model picker.
  2. Observe that the GPT-5.6 entries are absent under the custom provider.
  3. Set model = "gpt-5.6-sol" directly, or invoke the same provider from Codex CLI, and observe that the model request succeeds.
  4. 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:

  1. Configure a custom provider with API-key auth and a mock /models response.
  2. Assert that an online refresh reaches that endpoint and updates app-server model/list.
  3. Assert that a visible provider model is retained by the Desktop picker.

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 10 days ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #31873
  • #32049
  • #32080
  • #31882

Powered by Codex Action

chenty2333 · 10 days ago

Thanks — I reviewed the suggested issues and believe this report is distinct:

  • #31873 concerns the CLI/TUI picker with ChatGPT authentication, not an API-key custom provider.
  • #32049 concerns a Windows account/update/Statsig filtering regression where app-server model/list already contains GPT-5.6.
  • #32080 is specific to Remote SSH projects with a populated model cache.
  • #31882 concerns Azure inference requests failing because of Responses-Lite and collaboration-tool metadata, rather than remote catalog refresh or picker discovery.

The closest related report is #15843, but #32119 adds a current 0.144.1 reproduction for a custom provider whose authenticated /models endpoint returns a complete Codex manifest, plus the Codex App picker behavior. The current should_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.

jay-tau · 10 days ago

Confirmed on a concrete Windows installation:

  • Codex Desktop: 26.707.3748.0
  • Bundled app-server: 0.144.0-alpha.4
  • Platform: Microsoft Windows NT 10.0.26200 x64
  • Custom Responses provider with requires_openai_auth = false
  • Explicit model: gpt-5.6-sol

Observed behavior:

  1. The bundled app-server's model/list response contains seven visible models, including gpt-5.6-sol, gpt-5.6-terra, and gpt-5.6-luna.
  2. Codex Desktop's picker shows only GPT-5.5, GPT-5.4, GPT-5.4 Mini, and GPT-5.2. The explicitly configured Sol model is displayed only as Custom.
  3. A real thread/start + turn/start through the exact bundled app-server with modelProvider set to the custom provider, model gpt-5.6-sol, and effort xhigh completed successfully. The provider logged POST /v1/responses 200 for gpt-5.6-sol.
  4. Desktop logs show model/list completing 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.

FancyQian · 10 days ago

Confirmed my side as well.

jojodat · 10 days ago

Seems to be also on K12 Teacher Workspaces

Menci · 10 days ago

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-parses use_hidden_models, available_models, default_model off the Statsig dynamic-config payload
  • ay() — reads eee('107580212').value
  • Jv({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):

Object.values(__STATSIG__.instances)[0].getDynamicConfig('107580212').value
// -> { use_hidden_models: true, default_model: 'gpt-5.4',
//      available_models: ['gpt-5.5','gpt-5.4','gpt-5.4-mini','gpt-5.3-codex','gpt-5.2'] }

For any non-ChatGPT-authed session (API-key, Azure, custom OpenAI-compatible) the whitelist branch runs and every hidden:false model that app-server model/list returned — 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):

ASAR=/Applications/ChatGPT.app/Contents/Resources/app.asar
OFF=$(grep -aboE 'use_hidden_models' "$ASAR" | head -1 | cut -d: -f1)
printf 'Z' | dd of="$ASAR" bs=1 seek=$((OFF+16)) count=1 conv=notrunc
codesign --force --deep --sign - /Applications/ChatGPT.app

Renames the string literal inside $v() so safeParse(e.use_hidden_models) misses and the field defaults to false. Length-preserving (asar header untouched), idempotent, reversible. Works because EnableEmbeddedAsarIntegrityValidation fuse is OFF on shipped builds.

Fix at the source — any one of these:

  1. In Jv/ive: skip the whitelist branch when authMethod !== 'chatgpt'. Custom API-key providers shouldn't be gated by a ChatGPT-account-scoped rollout list.
  2. In Jv/ive: union availableModels with models.filter(m => !m.hidden) before the t.has() check, so provider-returned visible models can never be dropped.
  3. Server-side: exclude non-ChatGPT-authed sessions from Statsig config 107580212 targeting.

Happy to help verify a fix if useful.