shadcn-ui/ui · error · RegistryValidationError
VALIDATION_ERROR
VALIDATION_ERROR
Error message
Invalid registry file at ${rootFile}: registries that use include must be named registry.json. What it means
Thrown by readRegistryWithIncludes when a registry file declares an 'include' array but is not itself named registry.json. shadcn enforces a naming convention: only a file literally named registry.json may act as the root of an include tree, because the include resolution logic and downstream path rewriting anchor on that basename. Without it, included chunks cannot be reliably resolved relative to a stable root.
Source
Thrown at packages/shadcn/src/registry/loader.ts:103
const source = {
registryFile: rootFile,
registryDir: context.cwd,
itemIndex,
}
context.itemSources.set(item.name, source)
context.itemSourcesByItem.set(item, source)
})
return {
registry: rootRegistry,
itemSources: context.itemSources,
itemSourcesByItem: context.itemSourcesByItem,
usesInclude,
}
}
if (path.basename(rootFile) !== "registry.json") {
throw new RegistryValidationError(
`Invalid registry file at ${rootFile}: registries that use include must be named registry.json.`,
{ registryFile: rootFile }
)
}
const result = await readRegistryFile(rootFile, rootRegistry, context, [])
validateDuplicateItems(result.items, context.itemSourcesByItem)
const { include, ...registry } = result
validateRootRegistry(registry, rootFile)
return {
registry,
itemSources: context.itemSources,
itemSourcesByItem: context.itemSourcesByItem,
usesInclude,
}View on GitHub (pinned to efac598707)
Solutions
- Rename the root registry file to registry.json (the literal basename must be 'registry.json').
- If you cannot rename the file, remove the 'include' field from it and instead point loadRegistry directly at the appropriate registry.json.
- Pass an explicit registryFile option that resolves to a path whose basename is registry.json.
Example fix
// before
// file: ./app-registry.json with { "include": ["./ui/registry.json"] }
await loadRegistry({ registryFile: "app-registry.json" })
// after
// rename file to ./registry.json
await loadRegistry({ registryFile: "registry.json" }) Defensive patterns
Strategy: validation
Validate before calling
import * as path from "path"
function assertRootRegistryName(registryFile: string, hasIncludes: boolean) {
if (hasIncludes && path.basename(registryFile) !== "registry.json") {
throw new Error(
`Root registry '${registryFile}' uses includes but is not named registry.json.`
)
}
}
// before calling loadRegistry:
const raw = JSON.parse(await fs.readFile(registryFile, "utf-8"))
assertRootRegistryName(registryFile, Array.isArray(raw.include) && raw.include.length > 0) Type guard
function isRootRegistryCandidate(file: string, content: unknown): boolean {
if (path.basename(file) !== "registry.json") return false
if (!content || typeof content !== "object") return false
const includes = (content as { include?: unknown }).include
return !Array.isArray(includes) || includes.length === 0 || path.basename(file) === "registry.json"
} Try / catch
try {
await loadRegistry({ registryFile })
} catch (err) {
if (err instanceof RegistryError && err.code === "VALIDATION_ERROR" && /must be named registry\.json/.test(err.message)) {
// rename the file or drop the include field
}
throw err
} Prevention
- Keep the root registry file named literally registry.json.
- Run a CI lint that asserts the root registry basename before build.
- Document the naming convention in your registry README.
When it happens
Trigger: Called loadRegistry({ registryFile }) or loadRegistryItem(name, { registryFile }) where the resolved root file contains an 'include' field (usesInclude === true) AND path.basename(rootFile) !== 'registry.json'. E.g. registryFile: 'my-registry.json' with {"include": ["./ui/registry.json"]}.
Common situations: Renaming the root registry file from registry.json to something project-specific (e.g. shadcn-registry.json, app-registry.json) while keeping the include field. Copying a registry config from a sub-package to the repo root without renaming. Migrating from a flat registry to a split one and forgetting the rename.
Related errors
- VALIDATION_ERROR
- Base color "${baseColorName}" or theme "${themeName}" not fo
- Unknown item: "${designSystemConfig.item}".
- Base color "${config.baseColor}" or theme "${config.theme}"
- Base "${config.base}" or icon library "${config.iconLibrary}
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/914c1519e5ec3e1a.
Report an issue: GitHub.