Skip to content

[Bug]: Routed models are loaded by Codex app-server but missing from Desktop model picker #241

Closed

Description

@Lingchen97

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_json and openai_base_url are present as root settings.
  • opencodex-catalog.json contains all 13 routed entries with visibility: "list".
  • The Codex Desktop bundled CLI's codex debug models reads all 13 routed entries.
  • A direct model/list request to the bundled Codex app-server also returns all routed entries.
  • Fully quitting and reopening Codex Desktop does not change the picker.

Reproduction

  1. 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"
        }
      }
    }
  2. Run ocx start.

  3. Confirm that ~/.codex/config.toml contains:

    model_catalog_json = "/Users/example/.codex/opencodex-catalog.json"
    openai_base_url = "http://127.0.0.1:10100/v1"
  4. Confirm that the generated catalog contains routed models with visibility: "list".

  5. 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.

  6. Fully quit and reopen Codex Desktop.

  7. Open the model picker.

  8. 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         list

Additional 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_models allowlist when the remote use_hidden_models setting 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

  1. Wibias commented on Jul 22, 2026

    @Wibias
    Contributor

    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 via model/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_models setting is active, the picker switches from catalog visibility to an available_models allowlist 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:

    1. Check whether the use_hidden_models remote 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).
    2. The Codex CLI (codex in 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.
  2. lidge-jun commented on Jul 22, 2026

    @lidge-jun
    Owner

    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.

  3. added
    upstream-trackingBlocked on an upstream (Codex CLI/Desktop) fix; kept open for discoverability
    bugSomething isn't working
    on Jul 22, 2026
  4. lidge-jun commented on Jul 23, 2026

    @lidge-jun
    Owner

    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_models allowlist that the proxy cannot influence. No supported proxy-side override exists.

    Keeping open for upstream tracking; will update when the Desktop picker behavior changes.

  5. added
    catalogModel catalog, slugs, visibility, routed entries
    on Aug 1, 2026
  6. Killin-7 commented on Aug 1, 2026

    @Killin-7
  7. github-actions commented on Aug 1, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: unknown.

  8. lidge-jun commented on Aug 2, 2026

    @lidge-jun
    Owner

    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.

  9. Repository owner deleted a comment from Killin-7 on Aug 3, 2026
  10. lidge-jun commented on Aug 3, 2026

    @lidge-jun
    Owner

    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 root model_catalog_json key is written into the Codex config at src/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_models allowlist, 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.

  11. Yuxin-Qiao commented on Aug 4, 2026

    @Yuxin-Qiao
    Contributor

    Triage update: the upstream bug behind this Desktop-side filter now has a linked ticket.

    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 to codex-app-models.md.]

  12. lidge-jun commented on Aug 9, 2026

    @lidge-jun
    Owner

    Fixed on dev as 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.

  13. wzp100 commented on Sep 24, 2026

    @wzp100

    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/opencodex 2.59.0. Native Codex account login remained in use.

    Before the fix

    • ocx status: proxy healthy, but routing=unknown.
    • ocx sync reported + 4 models appended to Codex catalog, then:
      External provider owns config.toml; catalog and models cache refreshed, Codex config/journal untouched.
      
    • The generated catalog was valid and contained nine entries, including four third-party models. However, the initial root config.toml had no model_catalog_json or openai_base_url. A codex debug models keyword check showed no matching third-party models.
    • Relevant redacted configuration:
      model_provider = "custom"
      
      [model_providers.custom]
      name = "OpenAI"
      requires_openai_auth = true
      supports_websockets = true
      wire_api = "responses"
      The custom provider's display name and requires_openai_auth did not make its ID the built-in openai provider. The external-provider guard correctly avoided overwriting this configuration.

    Resolution confirmed by the user

    1. Back up config.toml.
    2. Remove the top-level model_provider = "custom" (or select model_provider = "openai") only if the intended setup is to route the built-in OpenAI provider via OpenCodex. Keep the existing [model_providers.*] definitions.
    3. Re-run ocx sync and restart Codex/app-server processes if needed.
    4. Verify that the root config now contains model_catalog_json and openai_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/list comparison was collected, so this case should not be treated as evidence against the Desktop allowlist issue reported in #241.

    Suggested troubleshooting note: when ocx sync says External provider owns config.toml, inspect the active top-level model_provider and 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.

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 entriesupstream-trackingBlocked on an upstream (Codex CLI/Desktop) fix; kept open for discoverability

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions