{"record":{"id":"d024681dbb2af9bb","repo":"shadcn-ui/ui","slug":"failed-to-fetch-components-from-registry-d02468","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/dry-run.ts","lineNumber":100,"sourceCode":"  const result: DryRunResult = {\n    files: [],\n    dependencies: [],\n    devDependencies: [],\n    css: null,\n    envVars: null,\n    fonts: [],\n    docs: null,\n  }\n\n  if (!components.length) {\n    return result\n  }\n\n  // Resolve the registry tree (read-only).\n  let tree = await resolveRegistryTree(components, configWithDefaults(config))\n\n  if (!tree) {\n    throw new Error(\"Failed to fetch components from registry.\")\n  }\n\n  // Massage tree for fonts (read-only).\n  if (!options.skipFonts) {\n    tree = await massageTreeForFonts(tree, config)\n  }\n  const supportedFontMarkers = getSupportedFontMarkers([tree])\n\n  // Dependencies pass through deduplicated.\n  result.dependencies = Array.from(new Set(tree.dependencies ?? []))\n  result.devDependencies = Array.from(new Set(tree.devDependencies ?? []))\n\n  // Docs pass through directly.\n  result.docs = tree.docs ?? null\n\n  // Process files.\n  await processFiles(tree, config, result, options, supportedFontMarkers)\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/utils/dry-run.ts#L82-L118","documentation":"Thrown by the dry-run pipeline (dryRun) when resolveRegistryTree(components, config) returns a falsy value. Identical root cause to the add-path error but in the read-only dry-run flow: the registry tree could not be resolved, so there is nothing to preview.","triggerScenarios":"Running a dry-run preview for a set of components where the registry fetch yields no tree. The check `if (!tree)` fires right after resolveRegistryTree and before font massaging and file processing.","commonSituations":"Network error or unreachable registry during preview; wrong component names; registry returning an empty/invalid tree payload; dry-running against a registry URL that requires auth that was not provided.","solutions":["Confirm the registry URL/namespace resolves and is reachable (curl the endpoint).","Check the component names passed into the dry run.","Provide any required auth/env so the registry returns a full tree.","Retry once to rule out a transient network blip."],"exampleFix":"# before\ndryRun(['nonexistent-item'], config)\n# after\ndryRun(['button'], config)\ncurl -s https://your-registry.example.com/r/button.json","handlingStrategy":"retry","validationCode":"const tree = await resolveRegistryTree(components, configWithDefaults(config))\nif (!tree) throw new Error(`could not resolve tree for: ${components.join(\", \")}`)","typeGuard":"const hasResolvedTree = (t: unknown): t is NonNullable<typeof t> =>\n  !!t && typeof t === \"object\"","tryCatchPattern":"try {\n  await dryRun(components, config)\n} catch (e) {\n  if (e instanceof Error && /Failed to fetch components/.test(e.message)) {\n    // fall back to a local/cached registry or retry\n  }\n}","preventionTips":["Confirm component names exist in the registry catalog before dry-running.","Ensure auth/env needed by the registry is set.","Cache registry responses in CI to avoid transient fetch failures."],"tags":["registry","network","dry-run","fetch"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}