shadcn-ui/ui · error
We could not find a valid `ui` path in your `components.json
Error message
We could not find a valid `ui` path in your `components.json` file. Please ensure you have a valid `ui` path in your `components.json` file.
What it means
Thrown by migrateRadix when no --path was given and config.resolvedPaths.ui is falsy. The default behavior is to scan the configured `ui` directory; without it the migrator has no fallback. The message instructs the user to fix components.json.
Source
Thrown at packages/shadcn/src/migrations/migrate-radix.ts:148
files = await fg("**/*.{js,ts,jsx,tsx}", {
cwd: basePath,
onlyFiles: true,
ignore: ["**/node_modules/**"],
})
} else if (stat.isFile()) {
files = [options.path]
} else {
throw new Error(`Unsupported path type: ${options.path}`)
}
}
if (files.length === 0) {
throw new Error(`No files found matching: ${options.path}`)
}
} else {
// Default: use ui path from components.json.
if (!config.resolvedPaths.ui) {
throw new Error(
"We could not find a valid `ui` path in your `components.json` file. Please ensure you have a valid `ui` path in your `components.json` file."
)
}
basePath = config.resolvedPaths.ui
files = await fg("**/*.{js,ts,jsx,tsx}", {
cwd: basePath,
onlyFiles: true,
})
}
// Confirm with user.
if (!options.yes) {
const relativePath = options.path
? options.path
: `./${path.relative(config.resolvedPaths.cwd, basePath)}`
const { confirm } = await prompts({View on GitHub (pinned to efac598707)
Solutions
- Add `aliases.ui` to components.json (e.g. "@/components/ui").
- Re-run `npx shadcn@latest init`.
- Pass `--path` to bypass the ui-path fallback.
- Programmatic callers: resolve Config via get-config before calling migrateRadix.
Example fix
// before — components.json without aliases.ui
"aliases": { "components": "@/components" }
// after
"aliases": { "components": "@/components", "ui": "@/components/ui" } Defensive patterns
Strategy: validation
Validate before calling
function assertUiPathForRadix(config: Config) {
if (!config.resolvedPaths.ui) {
throw new Error('Run `npx shadcn@latest init` to set aliases.ui, or pass --path.')
}
}
if (!options.path) assertUiPathForRadix(config) Type guard
function hasUiPath(c: Partial<Config>): c is Config & { resolvedPaths: { ui: string } } {
return Boolean(c.resolvedPaths?.ui)
} Try / catch
try {
await migrateRadix(config)
} catch (e) {
if (e instanceof Error && e.message.includes('valid `ui` path')) {
await migrateRadix(config, { path: './src/components/ui' })
} else throw e
} Prevention
- Keep components.json's aliases complete and under source control.
- Programmatic callers: resolve Config via get-config first.
- Default to passing --path in automation to avoid depending on aliases.
When it happens
Trigger: Running `shadcn migrate radix` (no --path) on a project whose components.json lacks `aliases.ui`; programmatic call to migrateRadix with a Config missing resolvedPaths.ui.
Common situations: Hand-edited components.json with the `ui` alias removed; project never ran `shadcn init`; partial Config built programmatically without resolving aliases.
Related errors
- We could not find a valid `ui` path in your `components.json
- Could not find a valid `ui` path in your `components.json`.
- File not found: ${options.path}
- Unsupported path type: ${options.path}
- No files found matching: ${options.path}
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/bbaa895dcc00bc9d.
Report an issue: GitHub.