{"record":{"id":"a3ccafad4954f975","repo":"shadcn-ui/ui","slug":"a-full-project-config-is-required-to-add-non-unive","errorCode":null,"errorMessage":"A full project config is required to add non-universal registry items or dependencies.","messagePattern":"A full project config is required to add non-universal registry items or dependencies\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shadcn/src/registry/resolver.ts","lineNumber":289,"sourceCode":"\n        // Deduplicate URLs\n        const uniqueUrls = Array.from(new Set(registryUrls))\n        let result = await fetchRegistry(uniqueUrls, options)\n        const registryPayload = z.array(registryItemSchema).parse(result)\n        payload.push(...registryPayload)\n      }\n    }\n  }\n\n  if (!payload.length) {\n    return null\n  }\n\n  if (\n    options.requireUniversal &&\n    !payload.every((item) => isUniversalRegistryItem(item))\n  ) {\n    throw new Error(\n      \"A full project config is required to add non-universal registry items or dependencies.\"\n    )\n  }\n\n  // No deduplication - we want to support multiple items with the same name from different sources\n\n  // If we're resolving the index, we want to fetch\n  // the theme item if a base color is provided.\n  // We do this for index only.\n  // Other components will ship with their theme tokens.\n  if (\n    uniqueNames.includes(\"index\") ||\n    allDependencyRegistryNames.includes(\"index\")\n  ) {\n    if (config.tailwind.baseColor) {\n      const theme = await registryGetTheme(config.tailwind.baseColor, config)\n      if (theme) {\n        payload.unshift(theme)","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/registry/resolver.ts#L271-L307","documentation":"Thrown by resolveRegistryTree when options.requireUniversal is true AND at least one item in the resolved payload is not universal (isUniversalRegistryItem returns false). Universal items must have type `registry:item` or `registry:file`, and every declared file must have an explicit `target` and be of those same types. Unlike every other error here, this is a plain `new Error(...)` — NOT a RegistryError subclass — so it has no `.code`, `.suggestion`, or `.context`. Callers cannot distinguish it by code, only by message.","triggerScenarios":"Programmatic callers (e.g. add command in universal/dry mode, or any caller passing `{ requireUniversal: true }`) pass a component name like `button` whose resolved item is type `registry:ui`, which fails the universal check because its files have no explicit `target`.","commonSituations":"Running an `add`-like flow outside a configured project (no resolvedPaths) where the CLI forces requireUniversal; mixing regular shadcn components into a universal-only install pipeline; programmatic use of shadcn's API from a non-Shadcn project.","solutions":["Run `npx shadcn init` first so a full project config exists, then drop the `requireUniversal` option.","Restrict the input items to universal ones: type registry:item or registry:file with explicit `target` on every file.","If you're a programmatic caller, gate the option on whether `config.resolvedPaths` is fully populated."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { isUniversalRegistryItem } from \"@/src/registry/utils\";\n\nasync function safeResolveUniversal(names, config, opts) {\n  const tree = await resolveRegistryTree(names, config, { ...opts, requireUniversal: false });\n  const nonUniversal = (tree?.files ?? []).length; // crude; better: re-fetch items and check each\n  return tree;\n}\n\n// Better: gate the option on config completeness\nfunction shouldRequireUniversal(config: Config) {\n  return !config?.resolvedPaths?.cwd || !config?.resolvedPaths?.ui;\n}","typeGuard":"import { isUniversalRegistryItem } from \"@/src/registry/utils\";\nimport type { RegistryItem } from \"@/src/schema\";\n\nfunction isUniversal(item: RegistryItem | null | undefined): boolean {\n  return isUniversalRegistryItem(item);\n}","tryCatchPattern":"// NOTE: this error is a plain Error, not a RegistryError — match by message.\ntry {\n  await resolveRegistryTree(names, config, { requireUniversal: true });\n} catch (e) {\n  if (e instanceof Error && /full project config is required/.test(e.message)) {\n    // re-run without requireUniversal, or guide the user to run `shadcn init`\n  }\n  throw e;\n}","preventionTips":["Only set requireUniversal when you have intentionally restricted inputs to registry:item / registry:file items with explicit targets.","Gate requireUniversal on whether config.resolvedPaths is fully populated (i.e. a real project is present).","Run `npx shadcn init` before invoking add flows so a full config exists."],"tags":["registry","universal","config","requirements"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}