shadcn-ui/ui · error · RegistryParseError
PARSE_ERROR
PARSE_ERROR
Error message
Failed to parse registry item: ${item} What it means
Thrown by fetchRegistryLocal when a local file was read and JSON.parse succeeded, but registryItemSchema.parse failed. RegistryParseError wraps the ZodError (printed in the message) and points at the registry-item schema. The file exists and is valid JSON; its contents just do not match a single registry item.
Source
Thrown at packages/shadcn/src/registry/fetcher.ts:158
return `${url}:${headersHash}`
}
export async function fetchRegistryLocal(filePath: string) {
try {
// Handle tilde expansion for home directory
let expandedPath = filePath
if (filePath.startsWith("~/")) {
expandedPath = path.join(homedir(), filePath.slice(2))
}
const resolvedPath = path.resolve(expandedPath)
const content = await fs.readFile(resolvedPath, "utf8")
const parsed = JSON.parse(content)
try {
return registryItemSchema.parse(parsed)
} catch (error) {
throw new RegistryParseError(filePath, error)
}
} catch (error) {
// Check if this is a file not found error
if (
error instanceof Error &&
(error.message.includes("ENOENT") ||
error.message.includes("no such file"))
) {
throw new RegistryLocalFileError(filePath, error)
}
// Re-throw parse errors as-is
if (error instanceof RegistryParseError) {
throw error
}
// For other errors (like JSON parse errors), throw as local file error
throw new RegistryLocalFileError(filePath, error)
}
}View on GitHub (pinned to efac598707)
Solutions
- Read the printed ZodError issues to find the failing field on the item.
- Confirm the file is a single item (has name, type, files), not a catalog (which has items[]).
- Validate against https://ui.shadcn.com/schema/registry-item.json.
- Use loadRegistry/loadRegistryItem for catalog files instead of fetchRegistryLocal.
Example fix
// before: local item file missing required 'type'
{ "name": "button", "files": [] }
// after
{
"name": "button",
"type": "registry:ui",
"files": [{ "path": "button.tsx", "type": "registry:ui", "target": "" }]
} Defensive patterns
Strategy: validation
Validate before calling
import { registryItemSchema } from "@/src/schema";
import * as fs from "fs/promises";
async function validateLocalItem(filePath: string) {
const json = JSON.parse(await fs.readFile(filePath, "utf8"));
const result = registryItemSchema.safeParse(json);
if (!result.success) {
throw new Error(`Item schema error: ${result.error.message}`);
}
return result.data;
} Type guard
function isRegistryItem(json: unknown): boolean {
return registryItemSchema.safeParse(json).success;
} Try / catch
try {
await fetchRegistryLocal(filePath);
} catch (err) {
if (err instanceof RegistryParseError) {
// err.parseError holds the ZodError; show field-level issues to fix the file
}
throw err;
} Prevention
- Validate local item files with registryItemSchema before committing.
- Use loadRegistryItem for catalog files; fetchRegistryLocal is for single items only.
- Keep a JSON schema check in CI for all .json under your registry directory.
When it happens
Trigger: Pointing fetchRegistryLocal at a registry catalog JSON (which has 'items[]') instead of a single registry-item JSON, or at a hand-written item missing required fields (name, type, files with required keys).
Common situations: Confusing a catalog file for an item file, editing a local item JSON and dropping a required field, or schema drift after upgrading the CLI's registry-item schema.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/f3e5f02746e27419.
Report an issue: GitHub.