shadcn-ui/ui · error · Error

Invalid registry schema for ${styleName}

Error message

Invalid registry schema for ${styleName}

What it means

registrySchema.safeParse guard inside buildRegistryJsonFile, which produces the installable public/r/styles/<style> JSON via the shadcn CLI. The style registry is imported from registry/<styleName>/registry.ts, parsed, and on failure the formatted Zod error is logged and 'Invalid registry schema for <styleName>' is thrown.

Source

Thrown at apps/v4/scripts/build-registry.mts:1348

    await formatGeneratedSource(index, outputPath)
  )

  await writeComponentShards(
    path.join(process.cwd(), "registry/__components__"),
    componentShards
  )
}

async function buildRegistryJsonFile(styleName: string) {
  const { registry: importedRegistry } = await import(
    `../registry/${styleName}/registry.ts`
  )

  const parseResult = registrySchema.safeParse(importedRegistry)
  if (!parseResult.success) {
    console.error(`❌ Registry validation failed for ${styleName}:`)
    console.error(parseResult.error.format())
    throw new Error(`Invalid registry schema for ${styleName}`)
  }

  const registry = parseResult.data

  // Legacy source styles (e.g. new-york-v4) don't author font items. Inject
  // the shared registry fonts so the shadcn CLI emits font-*.json for them,
  // matching the generated base/style combinations (which spread the same
  // fonts in their base registries). Font items have no files, so they pass
  // through every transform stage untouched.
  const registryItems = getStyleCombination(styleName)
    ? registry.items
    : [
        ...registry.items,
        ...fonts.filter(
          (font) => !registry.items.some((item) => item.name === font.name)
        ),
      ]

View on GitHub (pinned to efac598707)

Solutions

  1. Inspect the 'Registry validation failed for <styleName>' log for the precise field/path.
  2. Correct the item in registry/<styleName>/registry.ts.
  3. Run registrySchema.parse on the file in isolation to iterate.

Example fix

// before
{ type: "registry:ui", files: ["ui/dialog.tsx"] } // missing name

// after
{ name: "dialog", type: "registry:ui", files: ["ui/dialog.tsx"] }
Defensive patterns

Strategy: validation

Validate before calling

import { registrySchema } from "shadcn/schema"
const { registry } = await import(`../registry/${styleName}/registry.ts`)
const r = registrySchema.safeParse(registry)
if (!r.success) throw new Error(`${styleName}: ${JSON.stringify(r.error.format())}`)

Type guard

function isValidRegistry(value: unknown): boolean {
  return registrySchema.safeParse(value).success
}

Prevention

When it happens

Trigger: Running --registry <style> (or full build) when that style's registry.ts fails schema validation; legacy font injection logic expecting fields the registry no longer has.

Common situations: Authoring a new style registry with an invalid item; schema upgrade; CI registry export exposing a previously skipped style.

Related errors


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