shadcn-ui/ui · error
A full project config is required to resolve target aliases.
Error message
A full project config is required to resolve target aliases.
What it means
Plain Error thrown when the passed config did not fully parse (parsedConfig.success is false) AND hasResolvedTargetAliases returns false for the resolved tree. hasResolvedTargetAliases checks that every file in the tree whose `target` maps to a known alias key has that alias present in config.resolvedPaths. With a partial config, target aliases like `ui`, `lib`, etc. cannot be resolved, so installation would write to unknown locations.
Source
Thrown at packages/shadcn/src/registry/add.ts:86
)
const env = await loadEnvFiles(cwd, {
processEnv: { ...process.env },
})
return withRegistryContext(
async () => {
const resolvedTree = await resolveRegistryTree(items, config, {
useCache: true,
requireUniversal: !parsedConfig.success,
})
if (!resolvedTree) {
throw new Error("Failed to fetch components from registry.")
}
if (
!parsedConfig.success &&
!hasResolvedTargetAliases(resolvedTree, config)
) {
throw new Error(
"A full project config is required to resolve target aliases."
)
}
await addComponents(items, config, {
...addComponentsOptions,
interactive: false,
overwriteCssVars:
options.overwriteCssVars ??
(parsedConfig.success ? undefined : false),
resolvedTree,
})
},
{ env }
)
}
function hasResolvedTargetAliases(View on GitHub (pinned to efac598707)
Solutions
- Pass a full project Config resolved via get-config (so parsedConfig.success is true and the alias check is bypassed).
- If passing a partial config, ensure resolvedPaths includes every alias the requested items target (check each item's `target` field).
- Run `npx shadcn@latest init` first so components.json has all aliases, then let shadcn resolve the Config itself.
- Inspect the resolved tree's files[].target values to see which alias is missing.
Example fix
// before — partial config, items need ui/lib aliases
addRegistryItems(['button', 'use-toast'], {
config: { style: 'new-york' }
})
// after — pass a full config (resolved via get-config) including aliases
addRegistryItems(['button', 'use-toast'], {
config: {
style: 'new-york',
resolvedPaths: {
cwd: '/app',
ui: '/app/src/components/ui',
lib: '/app/src/lib',
hooks: '/app/src/hooks'
}
}
}) Defensive patterns
Strategy: validation
Validate before calling
import { configSchema } from '@/src/schema'
import { resolveRegistryTree } from '@/src/registry/resolver'
import { getTargetAliasKey } from '@/src/utils/target-aliases'
async function assertTargetAliasesResolvable(items: string[], config: Partial<Config>) {
const parsed = configSchema.safeParse(config)
if (parsed.success) return // full config — alias check is bypassed
const tree = await resolveRegistryTree(items, config as Config, { useCache: false })
if (!tree) return
const missing = (tree.files ?? [])
.map(f => getTargetAliasKey(f.target))
.filter(k => k && !config.resolvedPaths?.[k])
if (missing.length) {
throw new Error(`Partial config missing resolvedPaths for: ${Array.from(new Set(missing)).join(', ')}`)
}
}
await assertTargetAliasesResolvable(items, options.config ?? {}) Type guard
import { configSchema } from '@/src/schema'
function isFullConfig(c: unknown): c is Config {
return configSchema.safeParse(c).success
} Try / catch
try {
await addRegistryItems(items, { config: partial })
} catch (e) {
if (e instanceof Error && e.message.includes('full project config')) {
// re-resolve a full Config via get-config and retry
const full = await resolveFullConfig(cwd)
await addRegistryItems(items, { config: full })
} else throw e
} Prevention
- Pass a full Config resolved via get-config when installing items with target aliases.
- Inspect each item's `target` field to know which aliases are required.
- Run `shadcn init` so all alias paths exist before programmatic installs.
When it happens
Trigger: Calling addRegistryItems with a partial Config (no resolvedPaths for the required aliases) for items whose registry entries declare `target` fields (e.g. target: 'ui'); passing a config object that omits aliases but requesting items that need them.
Common situations: Embedding shadcn and passing a minimal `{ tailwind: {...} }` config while installing components that target ui/lib/hooks directories; CI scripts that skip running get-config.
Related errors
- INVALID_CONFIG
- The provided cwd must match config.resolvedPaths.cwd.
- VALIDATION_ERROR
- MISSING_ENV_VARS
- "${registryName}" is a built-in registry and cannot be overr
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/70208c1330c08163.
Report an issue: GitHub.