Codex Desktop resolves namespaced current model against wrong list, shows "Custom" and gpt-5.3-codex

Open
#37,700 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
55/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
javascript, rust
Domain
desktop

Research direction

Start with the bundled app-initial-*.js entry points around She() and The(), then trace which model list feeds current-model resolution versus the model/list result rendered by the picker. Reproduce with a provider-prefixed model such as custom_provider/gpt-5.6-sol and verify that the picker chip and /model use the custom catalog entry and reasoning options rather than the fallback.

Written by the indexing model from the issue text.

Description

app bug custom-model windows-os
What version of the Codex App are you using (From “About Codex” dialog)?

Codex Desktop 26.803.5235.0 (bundled codex-cli 0.147.0-alpha.6.5)

What subscription do you have?

Company-managed custom OpenAI-compatible provider; no direct ChatGPT subscription is used for this reproduction.

What platform is your computer?

Microsoft Windows 11 Pro 10.0.26200 (Build 26200.8875), x64

What issue are you seeing?

When Codex is configured with a custom model_provider and model_catalog_json, the Desktop model picker renders the custom catalog correctly but resolves the currently selected model against a different list than the one it displays.

The lookup misses, so:

  • The model picker chip displays "Custom" instead of the catalog entry's display_name.
  • /model reports gpt-5.3-codex as the current/default model, even though that model exists in neither the custom catalog nor the user configuration.
  • The reasoning-effort selector and model list render correctly from the custom catalog.
  • Routing still works: turns run on the configured model and the thread records that provider-prefixed model correctly.

Sanitized configuration shape:

# managed_config.toml
model_provider = "custom_provider"
model_catalog_json = "<path-to-custom-catalog>"

# config.toml
model = "custom_provider/gpt-5.6-sol"

The provider identifier, endpoint, credentials, and nonessential catalog identifiers are intentionally omitted or anonymized.

Potential root cause from the bundled app-initial-*.js

The current-model resolver matches the .model field using exact string equality:

function She(models, cfg) {
  return cfg == null ? null : models.find(m => m.model === cfg) ?? null;
}

function The({ automation, models }) {
  let n = She(models, automation.model);
  if (n != null) {
    return { model: n.model, reasoningEffort: Che({ model: n, ... }) };
  }

  // ...
  let r = whe(models);
  return r == null
    ? { model: automation.model ?? "gpt-5.3-codex", reasoningEffort: ... }
    : { model: r.model, reasoningEffort: ... };
}

At picker-resolution time, the models passed to The() appears to be the app's built-in cache, whose .model values are bare OpenAI slugs such as gpt-5.6-sol and gpt-5.3-codex. The model/list result rendered by the picker instead contains provider-prefixed values such as custom_provider/gpt-5.6-sol.

Therefore:

She(builtinList, "custom_provider/gpt-5.6-sol")

returns null, after which the label falls back to the localized composer.mode.local.model.custom value and the current model falls back to the hardcoded gpt-5.3-codex.

The routing layer resolves the same configured model against the custom catalog successfully, which explains why routing works while the current-model UI does not.

What steps can reproduce the bug?
  1. Configure a custom model_provider with a model_catalog_json whose model IDs carry a provider prefix, such as custom_provider/....
  2. Set config.toml model to one of those provider-prefixed IDs.
  3. Restart Codex Desktop so the managed configuration and catalog are loaded.
  4. Open the Desktop model picker.
  5. Observe that the model list and reasoning-effort choices render from the custom catalog, but the current-model chip displays "Custom".
  6. Run /model and observe that it reports gpt-5.3-codex.
  7. Start a turn and inspect the thread record or gateway routing; the configured provider-prefixed model is used correctly.
What is the expected behavior?

The picker should resolve the current model against the same model/list result it renders. A configured model that is present in that list should display its catalog name and supported reasoning options instead of falling back to "Custom" or an unrelated hardcoded model.

The preferred fix is to use the effective model/list result for current-model resolution. If that is not possible, namespace normalization could be a fallback before exact comparison, while preserving the custom catalog's metadata as authoritative.

Additional information

Evidence that display and resolution use different sources:

  • model/list over codex app-server returns the provider-prefixed model IDs that the picker renders.
  • A live turn records the same provider-prefixed model on the thread, confirming that routing resolved it.
  • The picker chip still displays "Custom" and /model reports gpt-5.3-codex.

Related but distinct reports:

  • #19694 and #34487 concern custom catalog models being hidden or omitted. In this reproduction, the catalog and model list render correctly.
  • #36582 reports a related custom-provider label problem plus incorrect session persona. In this reproduction, routing and recorded thread model are correct; the isolated failure is current-selection resolution, with the exact hardcoded gpt-5.3-codex fallback identified.
  • Merged PR #12658 added namespaced-model matching in the open-source model metadata path (oai/gpt-5.3-codexgpt-5.3-codex). That is useful precedent for handling provider-prefixed IDs, although the Desktop UI should preferably resolve against its effective custom catalog rather than substitute built-in metadata.
Dominant language
Rust
Stars
125k
Forks
19.5k
Avg merge
1m
Merged PRs (30d)
1k

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from openai/codex

All issues in openai/codex

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.