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

  1. Read the printed ZodError issues to find the exact failing path under 'registries'.
  2. Ensure each entry is either a URL string or an object with a string 'url' (and optional string 'headers'/'params').
  3. Run 'npx shadcn@latest init' to regenerate a known-good components.json.
  4. 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

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


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