shadcn-ui/ui · error

Base color "${baseColorName}" or theme "${themeName}" not fo

Error message

Base color "${baseColorName}" or theme "${themeName}" not found

What it means

buildTheme() in merge-theme.ts merges a base color and a theme into a registry:theme item. It looks each up by name in BASE_COLORS and THEMES (from @/registry/config) and throws if either lookup misses. It is the create-time UI equivalent of registry/config.ts buildRegistryTheme, guarding callers against unregistered names.

Source

Thrown at apps/v4/app/(app)/(create)/lib/merge-theme.ts:10

import { registryItemSchema, type RegistryItem } from "shadcn/schema"

import { BASE_COLORS, THEMES } from "@/registry/config"

export function buildTheme(baseColorName: string, themeName: string) {
  const baseColor = BASE_COLORS.find((c) => c.name === baseColorName)
  const theme = THEMES.find((t) => t.name === themeName)

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

  const mergedTheme: RegistryItem = {
    name: `${baseColor.name}-${theme.name}`,
    title: `${baseColor.title} ${theme.title}`,
    type: "registry:theme",
    cssVars: {
      light: {
        ...baseColor.cssVars?.light,
        ...theme.cssVars?.light,
      },
      dark: {
        ...baseColor.cssVars?.dark,
        ...theme.cssVars?.dark,
      },
    },

View on GitHub (pinned to efac598707)

Solutions

  1. Verify the base color name exists in BASE_COLORS (registry/base-colors.ts) and the theme name exists in THEMES (registry/themes.ts).
  2. Normalize casing and validate the names against those lists before calling buildTheme.
  3. If a name was renamed in the registry, migrate the caller to the new id.

Example fix

// before
buildTheme("Zinc", "Blue") // names are case-sensitive; registry uses lowercase

// after
buildTheme("zinc", "blue")
Defensive patterns

Strategy: validation

Validate before calling

import { BASE_COLORS, THEMES } from "@/registry/config"
const baseOk = BASE_COLORS.some((c) => c.name === baseColorName)
const themeOk = THEMES.some((t) => t.name === themeName)
if (!baseOk || !themeOk) {
  // reject or normalize input before calling buildTheme
}

Type guard

import { BASE_COLORS, THEMES } from "@/registry/config"
const BASE_NAMES = new Set(BASE_COLORS.map((c) => c.name))
const THEME_NAMES = new Set(THEMES.map((t) => t.name))
const isKnownBaseColor = (n: string): n is string => BASE_NAMES.has(n)
const isKnownTheme = (n: string): n is string => THEME_NAMES.has(n)

Try / catch

try {
  const theme = buildTheme(baseColorName, themeName)
} catch (e) {
  // surface a user-friendly "unknown base/theme" message
}

Prevention

When it happens

Trigger: Calling buildTheme(baseColorName, themeName) where either name is not exported by registry/base-colors.ts or registry/themes.ts; forwarding unvalidated URL or user input into buildTheme; a registry rename that the caller did not follow.

Common situations: Wiring the (create) style builder to new base/theme selectors; case mismatches (registry names are lowercase); presets persisted with now-renamed ids.

Related errors


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