{"record":{"id":"34b5a178e248892c","repo":"shadcn-ui/ui","slug":"local-file-error","errorCode":"LOCAL_FILE_ERROR","errorMessage":"Failed to read local registry file: ${filePath}","messagePattern":"Failed to read local registry file: (.+?)","errorType":"error_code","errorClass":"RegistryLocalFileError","httpStatus":null,"severity":"error","filePath":"packages/shadcn/src/registry/fetcher.ts","lineNumber":167,"sourceCode":"    }\n\n    const resolvedPath = path.resolve(expandedPath)\n    const content = await fs.readFile(resolvedPath, \"utf8\")\n    const parsed = JSON.parse(content)\n\n    try {\n      return registryItemSchema.parse(parsed)\n    } catch (error) {\n      throw new RegistryParseError(filePath, error)\n    }\n  } catch (error) {\n    // Check if this is a file not found error\n    if (\n      error instanceof Error &&\n      (error.message.includes(\"ENOENT\") ||\n        error.message.includes(\"no such file\"))\n    ) {\n      throw new RegistryLocalFileError(filePath, error)\n    }\n    // Re-throw parse errors as-is\n    if (error instanceof RegistryParseError) {\n      throw error\n    }\n    // For other errors (like JSON parse errors), throw as local file error\n    throw new RegistryLocalFileError(filePath, error)\n  }\n}\n","sourceCodeStart":149,"sourceCodeEnd":177,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/registry/fetcher.ts#L149-L177","documentation":"Thrown by fetchRegistryLocal in the outer catch when the underlying error message indicates the file does not exist (ENOENT or 'no such file'). RegistryLocalFileError wraps the original filesystem error and the resolved/expanded path that was attempted.","triggerScenarios":"Calling fetchRegistryLocal with a path that does not exist on disk (after tilde expansion and path.resolve), a typo'd filename, or running from the wrong working directory so the relative path misses.","commonSituations":"Wrong cwd, path passed before the file was created, '~/' expansion pointing at an unexpected HOME, or a path that was correct in a different checkout.","solutions":["Print process.cwd() and confirm the resolved path exists.","Use an absolute path or ensure you run from the directory containing the file.","Verify '~/...' paths expand to the intended HOME.","Create the file or fix the typo in the path."],"exampleFix":"// before\nfetchRegistryLocal(\"./registries/buton.json\")  // typo\n\n// after\nfetchRegistryLocal(\"./registries/button.json\")","handlingStrategy":"validation","validationCode":"import * as fs from \"fs\";\nimport path from \"path\";\n\nfunction assertFileExists(filePath: string, cwd = process.cwd()) {\n  const resolved = filePath.startsWith(\"~/\")\n    ? path.join(process.env.HOME ?? \"\", filePath.slice(2))\n    : path.resolve(cwd, filePath);\n  if (!fs.existsSync(resolved)) {\n    throw new Error(`Registry file not found: ${resolved} (from ${filePath})`);\n  }\n}","typeGuard":"import * as fs from \"fs\";\nfunction localRegistryFileExists(filePath: string): boolean {\n  try { return fs.existsSync(require(\"path\").resolve(filePath)); } catch { return false; }\n}","tryCatchPattern":"try {\n  await fetchRegistryLocal(filePath);\n} catch (err) {\n  if (err instanceof RegistryLocalFileError && /ENOENT|no such file/.test(err.message)) {\n    // show the resolved path and the cwd used, then prompt for the correct path\n  }\n  throw err;\n}","preventionTips":["Resolve paths against a known cwd and log the resolved absolute path on failure.","Expand '~/' explicitly and verify HOME is set in CI.","Check existence with fs.existsSync before calling fetchRegistryLocal."],"tags":["local-file","filesystem","enoent","typescript"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}