coleam00/Archon · error · Error

Alias name '${name}' is reserved (small/medium/large are tie

Error message

Alias name '${name}' is reserved (small/medium/large are tier keywords). Use a different name.

What it means

The model alias resolver reserves the tier keywords `small`, `medium`, and `large` for its built-in tier fallback system. `assertNotReserved` throws when a custom alias is defined using one of these names, because a custom alias would shadow or collide with tier lookup.

Source

Thrown at packages/workflows/src/model-validation.ts:85

const TIER_FALLBACK: Record<TierName, readonly TierName[]> = {
  large: ['large', 'medium', 'small'],
  medium: ['medium', 'large', 'small'], // prefer over-capable (large) when both sides missing
  small: ['small', 'medium', 'large'],
};

const TIER_DEFAULTS = tierDefaults as Record<
  string,
  Record<TierName, { model: string; effort?: string }>
>;

/** True when `value` is one of the reserved tier keywords (small/medium/large). */
export function isTierName(value: string): value is TierName {
  return (TIER_NAMES as readonly string[]).includes(value);
}

function assertNotReserved(name: string): void {
  if (isTierName(name)) {
    throw new Error(
      `Alias name '${name}' is reserved (small/medium/large are tier keywords). Use a different name.`
    );
  }
}

function assertCustomAliasPrefix(name: string): void {
  if (!name.startsWith('@')) {
    throw new Error(
      `Alias name '${name}' must start with '@' (e.g. '@${name}'). Reserved tier names (small/medium/large) do not need '@'.`
    );
  }
}

function assertValidEntry(name: string, entry: RawAliasEntry): void {
  if (typeof entry.provider !== 'string' || entry.provider.length === 0) {
    throw new Error(`Alias '${name}' has invalid provider — must be a non-empty string.`);
  }
  if (typeof entry.model !== 'string' || entry.model.length === 0) {

View on GitHub (pinned to 0773b97458)

Solutions

  1. Rename the alias to a non-reserved name (any name other than small/medium/large)
  2. If the goal is to override what `small`/`medium`/`large` resolve to, put the entry under `tiers:` instead of `aliases:`
  3. Custom aliases must also start with `@` — e.g. `@small-model`

Example fix

# before
aliases:
  large:
    provider: anthropic
    model: claude-opus-4
# after
aliases:
  '@big':
    provider: anthropic
    model: claude-opus-4
Defensive patterns

Strategy: validation

Validate before calling

import { isTierName } from '@archon/workflows/model-validation';
// Reject reserved alias names before writing config.
if (isTierName(aliasName)) {
  throw new Error(`'${aliasName}' is a reserved tier keyword; use tiers: config or pick another name`);
}

Type guard

function isSafeAliasName(name: string): boolean {
  return !['small', 'medium', 'large'].includes(name);
}

Try / catch

try {
  const profile = buildAiProfile(rawConfig);
} catch (err) {
  if (err instanceof Error && err.message.includes('is reserved (small/medium/large')) {
    throw new Error(`Config error: move the '${err.message.match(/'([^']+)'/)?.[1]}' entry into tiers: or rename it`, { cause: err });
  }
  throw err;
}

Prevention

When it happens

Trigger: Defining an alias named `small`, `medium`, or `large` in the `aliases:` config section, a run-model assignment, or a preset override target — any path that calls `buildAiProfile`, `presetForOverrideTarget`, or `parseRunModelAssignments` with that name.

Common situations: Users copying an entry from `tiers:` into `aliases:` without renaming it, intending to override tier defaults but placing the entry in the wrong config section.

Related errors


AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01). Data as JSON: /api/errors/e5c36c541d8fd9b6. Report an issue: GitHub.