shadcn-ui/ui · error · RegistryValidationError
VALIDATION_ERROR
VALIDATION_ERROR
Error message
Invalid source registry file at ${registryFile}: registries that use include must be named registry.json. What it means
Thrown by readSourceRegistryWithIncludes when the root registry declares an `include` array (so the include mechanism is in use) but the file's basename is not `registry.json`. shadcn enforces that any registry using includes must itself be named registry.json, so that included files can be addressed uniformly and the included-from metadata stays consistent. Fires only on the root file passed via options.registryFile.
Source
Thrown at packages/shadcn/src/registry/source.ts:118
registryFile,
registryDir,
itemIndex,
}
context.itemSources.set(item.name, source)
context.itemSourcesByItem.set(item, source)
})
validateDuplicateItems(rootRegistry.items, context.itemSourcesByItem)
return {
registry: rootRegistry,
itemSources: context.itemSources,
itemSourcesByItem: context.itemSourcesByItem,
usesInclude,
}
}
if (path.posix.basename(registryFile) !== "registry.json") {
throw new RegistryValidationError(
`Invalid source registry file at ${registryFile}: registries that use include must be named registry.json.`,
{ registryFile }
)
}
const result = await readRegistryFile(
registryFile,
rootRegistry,
reader,
context,
[]
)
validateDuplicateItems(result.items, context.itemSourcesByItem)
const { include, ...registry } = result
validateRootRegistry(registry, registryFile)
View on GitHub (pinned to efac598707)
Solutions
- Rename the root file to `registry.json` (the convention shadcn enforces).
- If you must keep a custom name, remove the `include` field from that file and inline the items directly.
Example fix
// before — file named my-registry.json with include
// my-registry.json
{ "include": ["./ui/registry.json"], "items": [] }
// after — rename file to registry.json and keep include
// registry.json
{ "include": ["./ui/registry.json"], "items": [] } Defensive patterns
Strategy: validation
Validate before calling
import path from "path";
function registryFileUsableWithIncludes(registryFile: string, root: { include?: string[] }) {
if (!root.include?.length) return { ok: true };
return path.posix.basename(registryFile) === "registry.json"
? { ok: true }
: { ok: false, reason: "include-requires-registry-json-name" };
} Type guard
function isCanonicalRegistryFileName(registryFile: string): boolean {
return path.posix.basename(registryFile) === "registry.json";
} Try / catch
import { RegistryValidationError } from "@/src/registry/errors";
try {
await loadRegistryItemFromSource(name, reader, { registryFile: "my-registry.json" });
} catch (e) {
if (e instanceof RegistryValidationError && /must be named registry.json/.test(e.message)) {
// rename file to registry.json and retry
}
throw e;
} Prevention
- Name your root registry file `registry.json` by convention.
- If you need a custom filename, don't use the `include` feature.
When it happens
Trigger: Calling `loadRegistryItemFromSource(name, reader, { registryFile: 'my-registry.json' })` where my-registry.json has a non-empty `include` array.
Common situations: A custom build pipeline passes a non-default registryFile name; a team renamed their root registry for namespacing reasons but still wants to compose via includes.
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/2f8c796434ec2579.
Report an issue: GitHub.