shadcn-ui/ui · error · Error

"${registryName}" is a built-in registry and cannot be overr

Error message

"${registryName}" is a built-in registry and cannot be overridden.

What it means

Thrown by getRawConfig when a key under the user's "registries" object in components.json collides with a name in BUILTIN_REGISTRIES (e.g. @shadcn). Built-in registries are merged in by the tool and cannot be overridden by user config, so any collision aborts config loading.

Source

Thrown at packages/shadcn/src/utils/get-config.ts:210

}

export async function getRawConfig(
  cwd: string
): Promise<z.infer<typeof rawConfigSchema> | null> {
  try {
    const configResult = await explorer.search(cwd)

    if (!configResult) {
      return null
    }

    const config = rawConfigSchema.parse(configResult.config)

    // Check if user is trying to override built-in registries
    if (config.registries) {
      for (const registryName of Object.keys(config.registries)) {
        if (registryName in BUILTIN_REGISTRIES) {
          throw new Error(
            `"${registryName}" is a built-in registry and cannot be overridden.`
          )
        }
      }
    }

    return config
  } catch (error) {
    const componentPath = `${cwd}/components.json`
    if (error instanceof Error && error.message.includes("reserved registry")) {
      throw error
    }
    throw new Error(
      `Invalid configuration found in ${highlighter.info(componentPath)}.`
    )
  }
}

View on GitHub (pinned to efac598707)

Solutions

  1. Remove the built-in registry key (e.g. "@shadcn") from the "registries" object in components.json.
  2. If you need a custom registry, give it a different namespace name that is not built-in (e.g. "@myorg").
  3. Re-run the command after editing the config.

Example fix

// components.json (before)
{
  "registries": { "@shadcn": "https://my-fork.example.com/r" }
}
// after
{
  "registries": { "@myorg": "https://my-fork.example.com/r" }
}
Defensive patterns

Strategy: validation

Validate before calling

import { BUILTIN_REGISTRIES } from "@shadcn/registry" // names list
for (const name of Object.keys(userConfig.registries ?? {})) {
  if (name in BUILTIN_REGISTRIES) {
    throw new Error(`${name} is built-in; rename your registry key`)
  }
}

Type guard

const isBuiltinRegistryName = (name: string, builtins: Record<string, unknown>) =>
  name in builtins

Try / catch

try {
  await getRawConfig(cwd)
} catch (e) {
  if (e instanceof Error && /built-in registry/.test(e.message)) {
    // strip the offending key and retry
  }
  throw e
}

Prevention

When it happens

Trigger: components.json (or package.json registries) contains a "registries" object whose keys include a built-in namespace. The loop checks `registryName in BUILTIN_REGISTRIES` and throws on the first match.

Common situations: User tries to point @shadcn at a fork/mirror; copy-pasted config that redeclares the default registry; migrating a config that predates built-in registries.

Related errors


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