shadcn-ui/ui · error

Failed to read config at ${options.cwd}.

Error message

Failed to read config at ${options.cwd}.

What it means

In the `shadcn add` command, after the optional init path, if no components.json config could be loaded (config still falsy), it throws pointing at options.cwd. It means neither an existing config was read nor did runInit produce one, so there is no target project to add components into.

Source

Thrown at packages/shadcn/src/commands/add.ts:274

          defaults: false,
          skipPreflight: true,
          silent: !hasNewRegistries && options.silent,
          isNewProject: true,
          cssVariables: true,
          rtl: false,
          installStyleIndex,
          components: [cleanInitUrl, ...(options.components ?? [])],
          registryBaseConfig,
        })
        initHasRun = true

        shouldUpdateAppIndex =
          options.components?.length === 1 &&
          !!options.components[0].match(/\/chat\/b\//)
      }

      if (!config) {
        throw new Error(
          `Failed to read config at ${highlighter.info(options.cwd)}.`
        )
      }

      const { config: updatedConfig } = await ensureRegistriesInConfig(
        options.components,
        config,
        {
          silent: options.silent || hasNewRegistries,
          writeFile: !isDryRun,
        }
      )
      config = updatedConfig

      // Dry-run mode: preview changes without writing files.
      // --diff and --view imply --dry-run.
      if (isDryRun) {
        const dryRunSpinner = spinner("Resolving items.", {

View on GitHub (pinned to efac598707)

Solutions

  1. Run `shadcn init` first (or allow add to trigger init) to create components.json.
  2. Confirm --cwd points at the project root that contains components.json.
  3. Check file read permissions on the cwd.

Example fix

# before
shadcn add button   # in a dir with no components.json, init skipped

# after
shadcn init
shadcn add button
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from "node:fs"
import { join } from "node:path"
const cfgPath = join(options.cwd, "components.json")
if (!existsSync(cfgPath)) {
  // run `shadcn init` or surface a clear error before calling add
}

Type guard

import { existsSync } from "node:fs"
import { join } from "node:path"
const hasComponentsJson = (cwd: string): boolean =>
  existsSync(join(cwd, "components.json"))

Try / catch

try {
  await addHandler(options)
} catch (e) {
  if (/Failed to read config/.test((e as Error).message)) {
    // prompt to run init, then retry
  } else throw e
}

Prevention

When it happens

Trigger: Running `shadcn add` in a directory without components.json with init skipped or failed; passing a --cwd that does not exist or lacks a config; file permissions preventing the read.

Common situations: First run in a fresh project where init was bypassed; wrong cwd in CI; corrupted or missing components.json.

Related errors


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