Repository navigation
Description
Problem
ModelAlias.resolveRef validates variants typed in the input and variants arriving via a model alias target (fixed for #398 in PR #403), but it never validates the value returned from the variant alias map (aliases.variants). A configured variant alias whose target is empty or contains a # produces a malformed or internally inconsistent ResolvedRef instead of the invalid-reference error every other path throws.
Evidence (verified 2026-10-24 on main c45147f)
File: packages/schema/src/model-alias.ts
resolveVariant(lines 202-233) returnsvariantAliases[...]verbatim, with no check that the target is non-empty and#-free.- The caller (lines 186-196) assigns that value straight to
finalVariantand buildscanonicalReffrom it, so the bad value lands in bothResolvedRef.variantandResolvedRef.ref. - By contrast
parseRefString(line 245) throws when a variant is empty or contains#, and the alias loop (lines 82-84) throws for the same shapes arriving in the input or via a model alias target.
Reproduction (Bun probe importing packages/schema/src/model-alias.ts, main c45147f):
| Aliases | Input | Result |
|---|---|---|
{ variants: { hi: "high#extra" } } |
openai/gpt-4o#hi |
returns { variant: "high#extra", ref: "openai/gpt-4o#high#extra" } — a ref parseRefString itself rejects |
{ variants: { hi: "" } } |
openai/gpt-4o#hi |
returns { variant: "", ref: "openai/gpt-4o" } — variant silently dropped, and variant is "" while ref carries no variant |
{ variants: { hi: "#" } } |
openai/gpt-4o#hi |
returns { variant: "#", ref: "openai/gpt-4o##" } |
Control: ModelAlias.resolve(undefined, "openai/gpt-4o#high#extra") throws Invalid model reference.
Why it matters
A typo or bad value in the variants alias map (user config) is silently turned into a canonical ref no other parser in the repo accepts, so it fails later — further from the cause — or is passed to a provider as a variant name that can never match. The empty-target shape is worse: resolution appears to succeed while quietly dropping the variant the user asked for, and ResolvedRef.variant === "" contradicts ResolvedRef.ref, which has no variant segment.
Acceptance criteria
- A variant alias target that is empty or contains
#throws the same invalid-reference error as the no-alias path, naming the offending reference. -
ResolvedRef.variantis never"": it is either a non-empty variant orundefined, and it always agrees withResolvedRef.ref. - New tests in
packages/core/test/model-alias.test.tscover the#-containing and empty variant-alias-target shapes (bare and scoped/wildcard variant keys); all existing model-alias tests still pass. - Dedup checked 2026-10-24: fix(schema): ModelAlias alias path accepts invalid variants the no-alias parser rejects — empty variant dropped, second # kept #398/PR fix(schema): validate variants on the alias path and settle chains at the depth limit #403 covered input variants and model-alias targets only; no open or closed issue tracks variant-alias (
aliases.variants) targets.
Single-repo: ModelAlias lives only in this repo's schema/core packages.
Activity
docs: record the #408, #406/#407 and #411 completions in ROADMAP Done (…