{"record":{"id":"3e3d9d2a04283d33","repo":"nexu-io/open-design","slug":"bad-request","errorCode":"BAD_REQUEST","errorMessage":"repository contains symbolic links, which are not allowed","messagePattern":"repository contains symbolic links, which are not allowed","errorType":"validation","errorClass":"LocalDesignSystemImportError","httpStatus":400,"severity":"error","filePath":"apps/daemon/src/design-systems/github-import.ts","lineNumber":62,"sourceCode":"  await mkdir(cloneRoot, { recursive: true });\n  const cloneDir = path.join(\n    cloneRoot,\n    `${parsed.owner}-${parsed.repo}-${importedAt.replace(/[^0-9a-z]/gi, '')}`,\n  );\n  const gitBin = options.gitBin ?? 'git';\n  const cloneArgs = ['clone', '--depth', '1'];\n  const branch = cleanBranch(options.branch);\n  if (branch) cloneArgs.push('--branch', branch);\n  cloneArgs.push(parsed.cloneUrl, cloneDir);\n\n  try {\n    await execGit(gitBin, cloneArgs, undefined, 120_000);\n    // Refuse a clone that contains symbolic links: the design-system readers and\n    // this importer follow symlinks, so a committed in-tree symlink pointing\n    // outside the clone (e.g. `README.md -> /etc/passwd`) would exfiltrate an\n    // arbitrary file into the imported design system. Mirrors installFromGithub.\n    if (await containsSymlink(cloneDir)) {\n      throw new LocalDesignSystemImportError(\n        'BAD_REQUEST',\n        'repository contains symbolic links, which are not allowed',\n      );\n    }\n    const [detectedBranch, commit] = await Promise.all([\n      readGitStdout(gitBin, ['-C', cloneDir, 'rev-parse', '--abbrev-ref', 'HEAD']),\n      readGitStdout(gitBin, ['-C', cloneDir, 'rev-parse', 'HEAD']),\n    ]);\n    const sourceBranch = branch ?? normalizeDetachedBranch(detectedBranch);\n    return await importLocalDesignSystemProject(cloneDir, userDesignSystemsRoot, {\n      now: new Date(importedAt),\n      fallbackName: parsed.repo,\n      ...(options.name ? { name: options.name } : {}),\n      ...(options.reservedIds ? { reservedIds: options.reservedIds } : {}),\n      ...(options.importMode ? { importMode: options.importMode } : {}),\n      ...(options.craftApplies ? { craftApplies: options.craftApplies } : {}),\n      source: {\n        type: 'github',","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/design-systems/github-import.ts#L44-L80","documentation":"After a shallow git clone, the daemon scans the clone tree with containsSymlink. If any symbolic link exists, import is refused with BAD_REQUEST. The design-system readers and this importer follow symlinks, so a committed in-tree symlink pointing outside the clone (e.g. README.md -> /etc/passwd) would exfiltrate an arbitrary file into the imported design system.","triggerScenarios":"The cloned GitHub repository contains at least one symbolic link in its tree. Detected after clone succeeds, before any design-system file is read.","commonSituations":"Monorepo tooling that commits symlinks; platform-specific symlink shims; adversarial repos deliberately planting escape symlinks; repos with symlinked config directories.","solutions":["Remove or resolve the symlinks in the source repository, then re-import.","Import from a branch or tag that does not contain the symlinks.","Fork the repo, replace symlinks with real files, and import the fork.","Clone locally, clean the symlinks, and use the local import path instead."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"null","typeGuard":"function isLocalDesignSystemImportError(err: unknown): err is LocalDesignSystemImportError {\n  return err instanceof Error && err.name === 'LocalDesignSystemImportError';\n}","tryCatchPattern":"try {\n  await importFromGithub(url, userRoot);\n} catch (err) {\n  if (isLocalDesignSystemImportError(err) && err.code === 'BAD_REQUEST' && /symbolic links/i.test(err.message)) {\n    // tell the user the source repo has symlinks; suggest a cleaned fork or local import\n  } else throw err;\n}","preventionTips":["Do not import repositories that commit symlinks; the guard exists to prevent file exfiltration.","Fork the repo and replace symlinks with real files before importing.","For repos you control, resolve symlinks at commit time so the tree is symlink-free."],"tags":["design-systems","github-import","security","symlink"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}