shadcn-ui/ui · error · ConfigParseError
INVALID_CONFIG
INVALID_CONFIG
Error message
Invalid ${configName} configuration in ${cwd}. What it means
Thrown by parseRegistriesConfig when registriesConfigFileSchema.safeParse(config) fails while loading the 'registries' block from either components.json or package.json. The ConfigParseError names which config file failed and embeds the ZodError issues so the offending field is visible.
Source
Thrown at packages/shadcn/src/registry/api.ts:265
},
"package.json"
)
}
return {
registries: {},
}
}
function parseRegistriesConfig(
cwd: string,
config: unknown,
configFile: "components.json" | "package.json"
) {
const result = registriesConfigFileSchema.safeParse(config)
if (!result.success) {
throw new ConfigParseError(cwd, result.error, configFile)
}
return {
registries: result.data.registries || {},
}
}
export async function getShadcnRegistryIndex() {
const [result] = await fetchRegistry(["index.json"])
return registryIndexSchema.parse(result)
}
export async function getRegistryStyles() {
try {
const [result] = await fetchRegistry(["styles/index.json"])
return stylesSchema.parse(result)View on GitHub (pinned to efac598707)
Solutions
- Read the printed ZodError issues to find the exact failing path under 'registries'.
- Ensure each entry is either a URL string or an object with a string 'url' (and optional string 'headers'/'params').
- Run 'npx shadcn@latest init' to regenerate a known-good components.json.
- Validate the file with a JSON linter before saving.
Example fix
// before: components.json
{
"registries": {
"@myorg": { "url": 123 }
}
}
// after
{
"registries": {
"@myorg": { "url": "https://example.com/r/{name}.json" }
}
} Defensive patterns
Strategy: validation
Validate before calling
import { registryConfigSchema } from "@/src/schema";
function validateRegistriesConfig(config: unknown) {
const result = z.object({ registries: registryConfigSchema.optional() })
.safeParse(config);
if (!result.success) {
throw new Error(`components.json registries invalid: ${result.error.message}`);
}
return result.data;
} Type guard
function isValidRegistriesBlock(config: unknown): boolean {
return z.object({ registries: registryConfigSchema.optional() })
.safeParse(config).success;
} Try / catch
try {
await getRegistriesConfig(cwd);
} catch (err) {
if (err instanceof ConfigParseError) {
// err.cause is the ZodError; show its issues, then offer to run `shadcn init`
}
throw err;
} Prevention
- Lint components.json as JSON before committing.
- Use object form for registries with headers/params; never mix types in values.
- Re-run 'npx shadcn@latest init' after a CLI upgrade to regenerate valid config.
When it happens
Trigger: A components.json with a malformed 'registries' object (e.g., a registry value that is neither a string nor a valid {url,headers,params} object), or a package.json whose top-level 'registries' field has the wrong shape. Also triggered by passing an explicitly loaded config whose registries entries fail registryConfigSchema.
Common situations: Editing components.json by hand and using a non-string header value, forgetting the 'url' key in an object-form registry entry, or JSON syntax errors in the registries block. Migrating config format between versions.
Related errors
- INVALID_CONFIG
- Invalid base: ${String(resolvedBase)}. Expected one of: ${PR
- Unknown client: ${client}. Available clients: ${CLIENTS.map(
- Something went wrong reading your `components.json` file. Pl
- We could not find a valid `ui` path in your `components.json
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/a8b02db0b5533bad.
Report an issue: GitHub.