nexu-io/open-design · error · LocalDesignSystemImportError

INTERNAL_ERROR

INTERNAL_ERROR

Error message

could not allocate design system id

What it means

The design system importer reserves a unique directory by trying slug through slug-999 under the user design-systems root (reserveNextAvailableSlug in import.ts:401). If all 999 candidate directories already exist, no free id can be allocated and the import aborts with INTERNAL_ERROR. This signals an unusual accumulation of same-named design systems rather than malformed user input.

Source

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

async function reserveNextAvailableSlug(
  root: string,
  preferred: string,
  reservedIds: Iterable<string> = [],
): Promise<string> {
  await mkdir(root, { recursive: true });
  const base = preferred || 'imported-design-system';
  const reserved = new Set(reservedIds);
  for (let index = 1; index < 1000; index += 1) {
    const id = index === 1 ? base : `${base}-${index}`;
    if (reserved.has(id)) continue;
    try {
      await mkdir(path.join(root, id));
      return id;
    } catch (error: any) {
      if (error?.code !== 'EEXIST') throw error;
    }
  }
  throw new LocalDesignSystemImportError('INTERNAL_ERROR', 'could not allocate design system id');
}

function renderManifest(
  id: string,
  name: string,
  scan: ProjectScan,
  now: Date,
  sourceOverride: DesignSystemProjectSource | undefined,
  importMode: 'normalized' | 'hybrid' | 'verbatim',
  craftApplies: string[],
) {
  const importedAt = now.toISOString();
  const source = sourceOverride ?? {
    type: 'local',
    path: scan.sourceRoot,
    importedAt,
  };
  return {

View on GitHub (pinned to 5be4028344)

Solutions

  1. Delete or archive stale design system directories sharing the same slug prefix under the user design systems root
  2. Pass a unique options.name on each import so the base slug differs
  3. If a legitimate large-scale need exists, raise the loop ceiling in reserveNextAvailableSlug (import.ts:409) or file a feature request for UUID-based fallback ids
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-scan for existing slug collisions before importing
import { readdir } from 'node:fs/promises';
import path from 'node:path';

async function estimateSlugAvailability(root: string, baseSlug: string): Promise<number> {
  let existing: string[] = [];
  try { existing = await readdir(root); } catch { /* root may not exist yet */ }
  const prefix = baseSlug + '-';
  const taken = existing.filter(name => name === baseSlug || (name.startsWith(prefix) && /^-\d+$/.test(name.slice(baseSlug.length))));
  return taken.length;
}

// Usage: if count is near 999, clean up before importing
const count = await estimateSlugAvailability(dsRoot, slugify(displayName));
if (count >= 990) {
  // warn user: nearly exhausted, clean up old imports first
}

Try / catch

import { LocalDesignSystemImportError } from './import.js';

try {
  await importLocalDesignSystemProject(sourceRoot, dsRoot, options);
} catch (err) {
  if (err instanceof LocalDesignSystemImportError && err.code === 'INTERNAL_ERROR') {
    // Data-state issue: 999 same-slug directories exist.
    // Surface to user: clean up old design systems or use a unique name.
    console.error('Design system slot exhaustion:', err.message);
    return;
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling importLocalDesignSystemProject or importShadcnDesignSystem more than 999 times where every display name slugifies to the same base slug (e.g., always 'shadcn design system') without cleaning up prior imports.

Common situations: Automated test or CI suites that repeatedly import the same-named design system; a design-systems root directory filled with orphaned slug directories from failed or abandoned imports.

Related errors


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