Skip to content

fix(api): alias-backed models leak raw node UUID prefix in /v1/models (#8958) - #8961

Merged
diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.50from
Rahulsharma0810:fix/alias-backed-models-node-prefix
Aug 6, 2026
Merged

diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.50from
Rahulsharma0810:fix/alias-backed-models-node-prefix

Conversation

@Rahulsharma0810

Copy link
Copy Markdown
Contributor

Summary

Fixes #8958. For an OpenAI-/Anthropic-compatible provider node with a custom prefix (node id is a UUID), GET /v1/models listed every alias-backed model twice: the correct prefix/model id and a duplicate raw <node-uuid>/model id — even under MODELS_CATALOG_PREFIX_MODE=alias.

Root cause

The alias-backed models loop (added in #4630) in src/app/api/v1/models/catalog.ts built its display prefix without consulting providerIdToPrefix:

const alias = providerIdToAlias[canonicalProviderId] || providerKey;

For a compatible node, canonicalProviderId is the UUID and providerIdToAlias[<uuid>] is undefined, so alias fell through to the raw UUID providerKey. The dedupe only compared alias/model and providerKey/model (both UUID-prefixed), so it never matched the correct prefix/model row already emitted by the synced-models loop. Additionally, the includeCanonical branch pushed ${canonicalProviderId}/${modelId} (= <uuid>/model) in default/dual modes — a second leak.

The synced-models (catalog.ts:896) and custom-models (catalog.ts:1245) loops already handle this correctly via const prefix = providerIdToPrefix[...] and a && !prefix guard on their canonical push. owned_by was also already masked by resolvePublicOwnerId (#8327) — only the published id leaked.

Fix

Mirror the sibling loops in the alias-backed block:

const nodePrefix = providerIdToPrefix[providerKey] || providerIdToPrefix[canonicalProviderId];
const alias = nodePrefix || providerIdToAlias[canonicalProviderId] || providerKey;

and add && !nodePrefix to the includeCanonical emit guard. The id collapses to prefix/model, which the existing dedupe skips; the canonical UUID row is no longer emitted for prefixed nodes.

Tests

Adds tests/unit/8958-alias-backed-node-prefix.test.ts (real-DB harness, same style as the #8327 test):

  • alias mode: exactly one prefix/model, no UUID-prefixed id anywhere
  • default and dual modes: prefix/model present, no <node-uuid>/… id

Verified locally:

  • new test: 2/2 pass
  • sibling 8327-models-owned-by-prefix.test.ts: 3/3 pass
  • models-catalog-route, models-catalog-hide-paid, catalog-helpers-extraction, cc-compatible-model-catalog, model-alias-provider-resolution: 69/69 pass

Also validated against a live instance running the equivalent patch: ?prefix=alias and default/dual drop the duplicate UUID entries while retaining the correct prefix/ rows; ?prefix=canonical is unchanged; routing via both the alias and the prefix/… id is unaffected.

…diegosouzapw#8958)

The alias-backed models loop in catalog.ts built its display prefix as
`providerIdToAlias[canonicalProviderId] || providerKey` and never consulted
`providerIdToPrefix`, unlike the synced-models and custom-models loops. For an
openai-/anthropic-compatible provider node (whose id is a UUID) the alias fell
through to the raw UUID `providerKey`, so `/v1/models` published a duplicate
`<node-uuid>/model` entry alongside the correct `prefix/model` one — even under
MODELS_CATALOG_PREFIX_MODE=alias, because the dedupe only compared UUID-prefixed ids.

Fix: resolve the display prefix through `providerIdToPrefix` first, and skip the
canonical (`includeCanonical`) emit when the node has a configured prefix — mirroring
the `&& !prefix` guard already used by the synced/custom loops (catalog.ts:896,1245).
`owned_by` was already masked via resolvePublicOwnerId (diegosouzapw#8327); only the id leaked.

Adds tests/unit/8958-alias-backed-node-prefix.test.ts covering alias, default and dual
prefix modes.
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
@diegosouzapw
diegosouzapw merged commit a9b4c3e into diegosouzapw:release/v3.8.50 Aug 6, 2026
4 of 5 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…diegosouzapw#8958) (diegosouzapw#8961)

Validated in local merge-train T5 (base49+contributors+pacocartones)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(api): /v1/models lists duplicate <node-uuid>/<model> entries for compatible providers with custom prefix

2 participants