Skip to content

[Bug] Registry model renames never reach existing key-auth provider configs (qwen3.8-max-preview persists) #1610

Closed

Description

@lidge-jun

Client or integration

OpenCodex dashboard

Area

Catalog / models

Summary

When a registry preset renames or retires a model id, existing key-auth provider configs are never updated. The stale id stays in config.json forever, so the dashboard keeps listing a model the vendor is retiring and the real replacement never appears.

Concrete case: d40367c0c renamed qwen3.8-max-preview to qwen3.8-max across both Alibaba Token Plan providers. My alibaba-token-plan-intl entry still carried the preview id in six places today, and alibaba-token-plan-intl/qwen3.8-max was simply absent from the picker.

The cause is the guard in reconcileOAuthProviders (src/oauth/index.ts:917):

if (!def || prov.authMode !== "oauth") continue;

OAUTH_RECONCILE_FIELDS already contains exactly the fields that go stale — models, modelContextWindows, modelInputModalities, modelReasoningEfforts, modelReasoningEffortMap — and there is already a heal step for a defaultModel that no longer exists in the refreshed list. None of it runs for authKind: "key" presets, because reconciliation is keyed on OAUTH_PROVIDERS and an oauth auth mode rather than on "this provider came from a registry preset".

So the repair path exists and is well tested; it is simply unreachable for every key-auth preset (Alibaba Token Plan, Moonshot, Volcengine, and the rest).

Reproduction

  1. Configure alibaba-token-plan-intl on a build from before d40367c0c (registry seeds qwen3.8-max-preview).
  2. Upgrade to any build after d40367c0c (registry seeds qwen3.8-max).
  3. Restart the service and open the dashboard model list for alibaba-token-plan-intl.

Observed: the list shows alibaba-token-plan-intl/qwen3.8-max-preview. alibaba-token-plan-intl/qwen3.8-max is not offered.

Expected: the retired id is replaced by the supported one, carrying the registry's current context window, modalities, and reasoning ladder.

Persisted state on my machine before the manual fix:

models[0]                              qwen3.8-max-preview
modelContextWindows                    qwen3.8-max-preview: 983616
modelInputModalities                   qwen3.8-max-preview: [text, image]
modelReasoningEfforts                  qwen3.8-max-preview: [low, high, xhigh]
modelDefaultReasoningEfforts           qwen3.8-max-preview: xhigh
preserveReasoningContentModels         includes qwen3.8-max-preview
thinkingBudgetModels                   includes qwen3.8-max-preview
disabledModels                         alibaba-token-plan-intl/qwen3.8-max-preview

Two of those had drifted from the registry beyond the rename, which is the part a plain string replacement would miss:

  • ladder was ["low","high","xhigh"]; the registry's QWEN38_REASONING_EFFORTS is ["low","medium","xhigh"]
  • the id sat in thinkingBudgetModels, but the registry puts qwen3.8-max in directReasoningEffortModels and explicitly filters it out of thinkingBudgetModels

A user who edits the id by hand keeps the wrong reasoning contract, silently.

Version

dev at acef0a584

Operating system

macOS

Provider and model

alibaba-token-plan-intl / qwen3.8-max (was qwen3.8-max-preview)

Logs or error output

No error is emitted. That is the problem: the rename fails silently and the only symptom is a model list that disagrees with the registry.

Screenshots and supporting files

Dashboard shows alibaba-token-plan-intl/qwen3.8-max-preview in the 1/15 model list for alibaba-token-plan-intl, with no qwen3.8-max row.

Redacted configuration

{
  "providers": {
    "alibaba-token-plan-intl": {
      "adapter": "openai-chat",
      "baseUrl": "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
      "authMode": "key",
      "apiKey": "<redacted>",
      "defaultModel": "qwen3.7-max",
      "models": ["qwen3.8-max-preview", "qwen3.7-max", "..."],
      "liveModels": false
    }
  }
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. coderabbitai commented on Aug 13, 2026

    @coderabbitai
    Contributor
    🔗 Related PRs

    #615 - feat: add Volcengine Ark Agent Plan provider [open]
    #652 - feat(providers): add bounded model discovery contract [merged]
    #653 - feat(providers): add Baseten Model APIs preset [merged]
    #870 - feat(providers): add SambaNova and Nebius presets [merged]
    #1535 - fix(providers): keep hand-edited context windows through a POST overwrite [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. added
    account-poolOAuth, credentials, Codex pool, quota, failover, plans
    catalogModel catalog, slugs, visibility, routed entries
    on Aug 13, 2026
  3. added a commit that references this issue on Aug 13, 2026
    3982dae
  4. lidge-jun commented on Aug 13, 2026

    @lidge-jun
    OwnerAuthor

    Fixed on dev in 3982dae.

    Root cause confirmed as filed: reconcileOAuthProviders skips any row whose authMode is not oauth, and enrichProviderFromRegistry is fill-only so it cannot rewrite a field that already has a value. Both behaviours are correct on their own — one protects hand-edited key-auth rows, the other protects explicit saved values — but together they leave no path for a model that was renamed rather than added.

    The fix is a declared rename table applied at startup (src/providers/model-rename-migration.ts), deliberately narrow rather than general reconciliation:

    • rewrites only ids listed in MODEL_RENAMES
    • only on a provider whose baseUrl still matches the registry entry or one of its baseUrlChoices — a row repointed at another vendor keeps its own ids
    • only when the registry currently seeds the replacement, so a stale table entry cannot write an unknown id
    • renames in place across models, the model-keyed records, the id lists, and defaultModel, preserving list order and collapsing a duplicate if both ids were present
    • drops the retired disabledModels row instead of renaming it: carrying that toggle across would hide the very model the rename exists to expose

    No config backup is taken, unlike the tier and region migrations. Those rewrite credentials and provider identity where a bad projection is unrecoverable; this one only touches model ids the registry no longer seeds, and the previous value is a string the migration still names.

    Verification:

    • 9 focused regressions in tests/model-rename-migration.test.ts, driven red first by ablating the projection to a no-op (4 failed), then green
    • replayed the exact stale config from the report: 6 preview references and the disabledModels row all resolved, models[0] becomes qwen3.8-max
    • full suite on Linux: 11536 pass / 0 fail across 718 files, bun run typecheck clean

    One thing worth flagging beyond the rename itself: the reported config had also drifted from the registry in ways a plain find-and-replace would have preserved incorrectly — the ladder was [low, high, xhigh] against the registry's [low, medium, xhigh], and the id sat in thinkingBudgetModels when the registry puts qwen3.8-max in directReasoningEffortModels. This migration renames the key rather than reseeding the value, so a config carrying drifted metadata keeps it. Making renamed models re-adopt registry metadata is a larger policy question about when a saved value stops being user intent, and is better decided on its own than folded in here.

  5. added 2 commits that reference this issue on Sep 17, 2026
    e06d65a
    d510262
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

    account-poolOAuth, credentials, Codex pool, quota, failover, plansbugSomething isn't workingcatalogModel catalog, slugs, visibility, routed entries

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions