{"record":{"id":"cc8efa6664afb074","repo":"coleam00/Archon","slug":"alias-name-name-must-start-with-e-g","errorCode":null,"errorMessage":"Alias name '${name}' must start with '@' (e.g. '@${name}'). Reserved tier names (small/medium/large) do not need '@'.","messagePattern":"Alias name '(.+?)' must start with '@' \\(e\\.g\\. '@(.+?)'\\)\\. Reserved tier names \\(small/medium/large\\) do not need '@'\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/workflows/src/model-validation.ts","lineNumber":93,"sourceCode":"  Record<TierName, { model: string; effort?: string }>\n>;\n\n/** True when `value` is one of the reserved tier keywords (small/medium/large). */\nexport function isTierName(value: string): value is TierName {\n  return (TIER_NAMES as readonly string[]).includes(value);\n}\n\nfunction assertNotReserved(name: string): void {\n  if (isTierName(name)) {\n    throw new Error(\n      `Alias name '${name}' is reserved (small/medium/large are tier keywords). Use a different name.`\n    );\n  }\n}\n\nfunction assertCustomAliasPrefix(name: string): void {\n  if (!name.startsWith('@')) {\n    throw new Error(\n      `Alias name '${name}' must start with '@' (e.g. '@${name}'). Reserved tier names (small/medium/large) do not need '@'.`\n    );\n  }\n}\n\nfunction assertValidEntry(name: string, entry: RawAliasEntry): void {\n  if (typeof entry.provider !== 'string' || entry.provider.length === 0) {\n    throw new Error(`Alias '${name}' has invalid provider — must be a non-empty string.`);\n  }\n  if (typeof entry.model !== 'string' || entry.model.length === 0) {\n    throw new Error(`Alias '${name}' has invalid model — must be a non-empty string.`);\n  }\n}\n\nfunction assertValidPersistedPreset(name: string, entry: ModelAliasPreset): void {\n  if (entry.effort !== undefined && !isEffortValidForProvider(entry.provider, entry.effort)) {\n    throw new Error(`Model binding '${name}' has an invalid effort.`);\n  }","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/coleam00/Archon/blob/0773b9745896ef0612e709c80845a0f7db315b19/packages/workflows/src/model-validation.ts#L75-L111","documentation":"Custom alias names must be prefixed with `@` so the resolver can distinguish them from bare model literals and tier keywords. `assertCustomAliasPrefix` throws when an alias key lacks the `@` prefix; the error message echoes the name with the suggested corrected form.","triggerScenarios":"Declaring an alias entry whose key does not start with `@` in the aliases config, a run-model assignment, or an override preset — any path through `buildAiProfile`, `presetForOverrideTarget`, or `parseRunModelAssignments`. Tier keywords (small/medium/large) are the only unprefixed names allowed, and those are rejected earlier by assertNotReserved in the aliases context.","commonSituations":"Copy-pasting config examples that omit the `@`, writing `myalias:` instead of `'@myalias':`, YAML quoting confusion around the `@` character (some tools need the key quoted).","solutions":["Add the `@` prefix to the alias key, quoting it in YAML: `'@name':`","Check the surrounding YAML didn't strip or mangle the `@` (quote the key if your YAML tool complains)","Remember the alias is later referenced as `@name` in workflow `model:` fields"],"exampleFix":"# before\naliases:\n  fast:\n    provider: openai\n    model: gpt-4o-mini\n# after\naliases:\n  '@fast':\n    provider: openai\n    model: gpt-4o-mini","handlingStrategy":"validation","validationCode":"// Ensure every custom alias key is @-prefixed before config load.\nfunction assertAliasPrefixes(aliases: Record<string, unknown>): void {\n  for (const key of Object.keys(aliases)) {\n    if (!['small', 'medium', 'large'].includes(key) && !key.startsWith('@')) {\n      throw new Error(`Alias '${key}' must start with '@'`);\n    }\n  }\n}","typeGuard":"function hasAliasPrefix(key: string): key is `@${string}` {\n  return key.startsWith('@');\n}","tryCatchPattern":"try {\n  const profile = buildAiProfile(rawConfig);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"must start with '@'\")) {\n    const name = err.message.match(/Alias name '([^']+)'/)?.[1] ?? '?';\n    throw new Error(`Config error: rename alias '${name}' to '@${name}'`, { cause: err });\n  }\n  throw err;\n}","preventionTips":["Quote @-prefixed YAML keys ('@fast':) so parsers do not mangle them","Grep alias config for keys missing the @ prefix in CI","Reference aliases in model: fields with the same @name spelling used in config","Document the @ convention in team config templates"],"tags":["config","model-alias","naming","yaml","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"0773b9745896ef0612e709c80845a0f7db315b19","analyzedAt":"2026-09-01T02:28:07.064Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}