{"record":{"id":"d26a5228f9eb1504","repo":"shadcn-ui/ui","slug":"we-found-an-unsafe-file-path-locationfield-in","errorCode":null,"errorMessage":"We found an unsafe file path \"${locationField}\" in the registry item. Installation aborted.","messagePattern":"We found an unsafe file path \"(.+?)\" in the registry item\\. Installation aborted\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/shadcn/src/utils/add-components.ts","lineNumber":466,"sourceCode":"      component.type === \"registry:base\"\n  )\n}\n\nexport function validateFilesTarget(\n  files: z.infer<typeof registryItemFileSchema>[],\n  cwd: string\n) {\n  for (const file of files) {\n    // `target` decides the write location when present; otherwise the path is\n    // derived from `file.path` (see resolveFilePath in update-files.ts). Both\n    // are registry-controlled, so validate whichever one is used.\n    const locationField = file?.target ?? file?.path\n    if (!locationField) {\n      continue\n    }\n\n    if (!isSafeTarget(locationField, cwd)) {\n      throw new Error(\n        `We found an unsafe file path \"${locationField}\" in the registry item. Installation aborted.`\n      )\n    }\n  }\n}\n","sourceCodeStart":448,"sourceCodeEnd":472,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/packages/shadcn/src/utils/add-components.ts#L448-L472","documentation":"Thrown by validateFilesTarget when isSafeTarget(locationField, cwd) returns false for a file's target (or path if target is absent). isSafeTarget rejects null bytes, URL-encoded traversal, \"..\" sequences, control characters, Windows drive letters outside Windows, and absolute/relative paths that resolve outside the project cwd. This is the security gate before any registry file is written to disk.","triggerScenarios":"During add/install, for each file in the resolved tree the locationField = file.target ?? file.path is tested. A target like \"../../etc/passwd\", \"%2e%2e/escape\", \"~/../x\", or one containing \\0 fails isSafeTarget and aborts installation.","commonSituations":"A malicious or buggy registry item ships a target/path that tries to write outside the project; URL-encoded traversal in a copied path; a target that accidentally contains \"..\"; cross-platform paths with drive letters run on macOS/Linux.","solutions":["Inspect the registry item's file.target and file.path values printed in the message; remove any \"..\", encoded sequences, null bytes, or drive letters.","If you control the registry, set target to a path inside the project (e.g. \"@/lib/utils\" or a relative path within cwd).","If the registry is third-party, do not install it; report the unsafe path to its maintainer.","Re-run the add command after the registry is fixed."],"exampleFix":"// registry item (before)\n{ \"path\": \"utils.ts\", \"target\": \"../../etc/secret\", \"type\": \"registry:lib\" }\n// after\n{ \"path\": \"utils.ts\", \"type\": \"registry:lib\" }","handlingStrategy":"validation","validationCode":"import { isSafeTarget } from \"@shadcn/utils\" // or replicate the function\nfor (const f of files) {\n  const loc = f.target ?? f.path\n  if (loc && !isSafeTarget(loc, cwd)) {\n    throw new Error(`unsafe target: ${loc}`)\n  }\n}","typeGuard":"function isSafeRelativeTarget(target: string, cwd: string): boolean {\n  if (target.includes(\"\\0\") || target.includes(\"..\")) return false\n  const resolved = path.resolve(cwd, target)\n  return resolved === cwd || resolved.startsWith(cwd + path.sep)\n}","tryCatchPattern":"try {\n  validateFilesTarget(tree.files ?? [], cwd)\n} catch (e) {\n  if (e instanceof Error && /unsafe file path/.test(e.message)) {\n    // abort install, report the offending registry\n  }\n}","preventionTips":["Only install registries you trust; review file.target values.","Keep targets as plain relative paths or @alias/subpath forms.","Reject any registry item whose target contains \"..\", encoded sequences, or null bytes.","Run validateFilesTarget yourself before committing to install."],"tags":["security","path-traversal","registry","add"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}