shadcn-ui/ui · error

Base color "${config.baseColor}" or theme "${config.theme}"

Error message

Base color "${config.baseColor}" or theme "${config.theme}" not found

What it means

buildRegistryTheme() in registry/config.ts is the canonical registry:theme builder. It resolves config.baseColor via getBaseColor and config.theme via getTheme and throws if either misses. Unlike merge-theme.ts buildTheme (create-time UI), this builds the registry item used by preset resolution and the CLI.

Source

Thrown at apps/v4/registry/config.ts:703

    return {
      success: false as const,
      error: `Invalid only value. Use one or more of: ${REGISTRY_BASE_PARTS.join(", ")}`,
    }
  }

  return {
    success: true as const,
    parts: Array.from(new Set(rawParts.map((part) => aliases[part]))),
  }
}

// Builds a registry:theme item from a design system config.
export function buildRegistryTheme(config: DesignSystemConfig) {
  const baseColor = getBaseColor(config.baseColor)
  const theme = getTheme(config.theme)

  if (!baseColor || !theme) {
    throw new Error(
      `Base color "${config.baseColor}" or theme "${config.theme}" not found`
    )
  }

  // Merge base color and theme CSS vars.
  const lightVars: Record<string, string> = {
    ...(baseColor.cssVars?.light as Record<string, string>),
    ...(theme.cssVars?.light as Record<string, string>),
  }
  const darkVars: Record<string, string> = {
    ...(baseColor.cssVars?.dark as Record<string, string>),
    ...(theme.cssVars?.dark as Record<string, string>),
  }
  const themeVars: Record<string, string> = {}

  // Apply chart color override.
  const chartTheme = getTheme(config.chartColor)
  if (chartTheme) {

View on GitHub (pinned to efac598707)

Solutions

  1. Validate config.baseColor and config.theme against getBaseColor/getTheme before calling buildRegistryTheme.
  2. When loading stored presets, migrate old ids to current names.
  3. Normalize casing; registry names are lowercase.

Example fix

// before
buildRegistryTheme({ ...config, theme: "NORD" }) // not registered / wrong case

// after
buildRegistryTheme({ ...config, theme: "nord" })
Defensive patterns

Strategy: validation

Validate before calling

import { getBaseColor, getTheme } from "@/registry/config"
if (!getBaseColor(config.baseColor) || !getTheme(config.theme)) {
  // reject or normalize the preset before building
}

Type guard

import { BASE_COLORS, THEMES } from "@/registry/config"
const isRegisteredBaseColor = (n: string) => BASE_COLORS.some((c) => c.name === n)
const isRegisteredTheme = (n: string) => THEMES.some((t) => t.name === n)

Try / catch

try {
  buildRegistryTheme(config)
} catch (e) {
  // map to a 400 "invalid preset" for the caller
}

Prevention

When it happens

Trigger: A DesignSystemConfig whose baseColor or theme is not present in BASE_COLORS/THEMES; constructing a config from unvalidated external input; a registry rename that config producers did not follow.

Common situations: Server-side preset resolution; CI/tests feeding synthetic configs; presets persisted with now-renamed theme or base-color ids.

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/8982f8f773ffbdd4. Report an issue: GitHub.