{"record":{"id":"a377ec67150dec5c","repo":"shadcn-ui/ui","slug":"failed-to-fetch-components-from-registry-a377ec","errorCode":null,"errorMessage":"Failed to fetch components from registry.","messagePattern":"Failed to fetch components from registry\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/shadcn/src/utils/add-components.ts","lineNumber":408,"sourceCode":"    logger.info(tree.docs)\n  }\n}\n\nasync function resolveAndValidateRegistryTree(\n  components: string[],\n  config: z.infer<typeof configSchema>,\n  options: AddComponentsOptions\n) {\n  const registrySpinner = spinner(`Checking registry.`, {\n    silent: options.silent,\n  })?.start()\n  const tree =\n    options.resolvedTree ??\n    (await resolveRegistryTree(components, configWithDefaults(config)))\n\n  if (!tree) {\n    registrySpinner?.fail()\n    throw new Error(\"Failed to fetch components from registry.\")\n  }\n\n  try {\n    validateFilesTarget(tree.files ?? [], config.resolvedPaths.cwd)\n  } catch (error) {\n    registrySpinner?.fail()\n    throw error\n  }\n\n  registrySpinner?.succeed()\n\n  return tree\n}\n\nasync function resolveOverwriteCssVars(\n  tree: NonNullable<Awaited<ReturnType<typeof resolveRegistryTree>>>,\n  components: z.infer<typeof registryItemSchema>[\"name\"][],\n  config: z.infer<typeof configSchema>,","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/utils/add-components.ts#L390-L426","documentation":"Thrown by the add-components pipeline when resolveRegistryTree returns a falsy value (null/undefined) for the requested components. resolveRegistryTree fetches and merges the registry catalog/tree; a falsy result means the fetch produced no usable tree. This is a generic top-level guard before file-target validation runs.","triggerScenarios":"Calling addComponents (or the add command path) where options.resolvedTree is not supplied and resolveRegistryTree(components, config) returns null. This typically follows a registry fetch that returned an empty/invalid payload, a network failure that resolved to an empty result, or an item set that resolved to nothing.","commonSituations":"Offline or flaky network when fetching a remote registry; registry endpoint returning 200 with an empty body or unexpected JSON; component names that do not match any registry entry causing the tree to collapse; proxy/corporate firewall blocking the registry host.","solutions":["Verify network connectivity and that the registry URL in components.json (or the @namespace) is reachable from your machine.","Check the component names passed to add; a typo can yield an empty resolved tree.","Retry the command; if it persists, fetch the registry URL directly with curl to inspect the response body and status.","Confirm the registry endpoint returns the expected registry-resolved-items-tree JSON shape."],"exampleFix":"# before — registry unreachable or wrong name\nnpx shadcn@latest add btton\n# after\nnpx shadcn@latest add button\ncurl -sI https://your-registry.example.com/r/button.json","handlingStrategy":"retry","validationCode":"const tree = await resolveRegistryTree(components, configWithDefaults(config))\nif (!tree) {\n  // check reachability before throwing\n  const res = await fetch(registryUrl)\n  if (!res.ok) throw new Error(`registry unreachable: ${res.status}`)\n  throw new Error('registry returned no tree')\n}","typeGuard":"const hasResolvedTree = (t: unknown): t is NonNullable<typeof t> =>\n  !!t && typeof t === \"object\" && Array.isArray((t as any).files)","tryCatchPattern":"try {\n  await addComponents(...)\n} catch (e) {\n  if (e instanceof Error && /Failed to fetch components/.test(e.message)) {\n    // retry once, or prompt user to check registry URL\n  }\n}","preventionTips":["Verify the registry URL is reachable (curl) before running add.","Pin registry URLs to a stable host you control for CI.","Pass options.resolvedTree when you have already fetched it to avoid refetch.","Add a retry wrapper for transient network failures."],"tags":["registry","network","add","fetch"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}