nexu-io/open-design · error · LocalDesignSystemImportError

BAD_REQUEST

BAD_REQUEST

Error message

repository contains symbolic links, which are not allowed

What it means

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.

Source

Thrown at apps/daemon/src/design-systems/github-import.ts:62

  await mkdir(cloneRoot, { recursive: true });
  const cloneDir = path.join(
    cloneRoot,
    `${parsed.owner}-${parsed.repo}-${importedAt.replace(/[^0-9a-z]/gi, '')}`,
  );
  const gitBin = options.gitBin ?? 'git';
  const cloneArgs = ['clone', '--depth', '1'];
  const branch = cleanBranch(options.branch);
  if (branch) cloneArgs.push('--branch', branch);
  cloneArgs.push(parsed.cloneUrl, cloneDir);

  try {
    await execGit(gitBin, cloneArgs, undefined, 120_000);
    // Refuse a clone that contains symbolic links: 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. Mirrors installFromGithub.
    if (await containsSymlink(cloneDir)) {
      throw new LocalDesignSystemImportError(
        'BAD_REQUEST',
        'repository contains symbolic links, which are not allowed',
      );
    }
    const [detectedBranch, commit] = await Promise.all([
      readGitStdout(gitBin, ['-C', cloneDir, 'rev-parse', '--abbrev-ref', 'HEAD']),
      readGitStdout(gitBin, ['-C', cloneDir, 'rev-parse', 'HEAD']),
    ]);
    const sourceBranch = branch ?? normalizeDetachedBranch(detectedBranch);
    return await importLocalDesignSystemProject(cloneDir, userDesignSystemsRoot, {
      now: new Date(importedAt),
      fallbackName: parsed.repo,
      ...(options.name ? { name: options.name } : {}),
      ...(options.reservedIds ? { reservedIds: options.reservedIds } : {}),
      ...(options.importMode ? { importMode: options.importMode } : {}),
      ...(options.craftApplies ? { craftApplies: options.craftApplies } : {}),
      source: {
        type: 'github',

View on GitHub (pinned to 5be4028344)

Solutions

  1. Remove or resolve the symlinks in the source repository, then re-import.
  2. Import from a branch or tag that does not contain the symlinks.
  3. Fork the repo, replace symlinks with real files, and import the fork.
  4. Clone locally, clean the symlinks, and use the local import path instead.
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

function isLocalDesignSystemImportError(err: unknown): err is LocalDesignSystemImportError {
  return err instanceof Error && err.name === 'LocalDesignSystemImportError';
}

Try / catch

try {
  await importFromGithub(url, userRoot);
} catch (err) {
  if (isLocalDesignSystemImportError(err) && err.code === 'BAD_REQUEST' && /symbolic links/i.test(err.message)) {
    // tell the user the source repo has symlinks; suggest a cleaned fork or local import
  } else throw err;
}

Prevention

When it happens

Trigger: The cloned GitHub repository contains at least one symbolic link in its tree. Detected after clone succeeds, before any design-system file is read.

Common situations: Monorepo tooling that commits symlinks; platform-specific symlink shims; adversarial repos deliberately planting escape symlinks; repos with symlinked config directories.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/3e3d9d2a04283d33. Report an issue: GitHub.