nexu-io/open-design · warning · Error

no projects on this daemon

Error message

no projects on this daemon

What it means

Thrown by resolveProjectId after fetchProjectList returned an empty array. The daemon has no projects at all, so no name or UUID can resolve. This is a state error, not a typo: the workspace is empty.

Source

Thrown at apps/daemon/src/mcp.ts:2970

      'project arg omitted and Open Design has no active project. The active context expires about 5 minutes after the last user interaction with Open Design - the user may need to click into a project to wake it up. Otherwise pass project="<id-or-name>".',
    );
  }
  return { id: active.projectId, resolved: null, active };
}

async function resolveProjectId(
  baseUrl: string,
  arg: unknown,
  headers?: Record<string, string>,
): Promise<ResolvedProject> {
  if (typeof arg !== 'string' || !arg) {
    throw new Error('project is required (string).');
  }
  if (UUID_RE.test(arg)) return { id: arg, name: arg, source: 'uuid' as const };

  const list = await fetchProjectList(baseUrl, headers);
  if (list.length === 0) {
    throw new Error('no projects on this daemon');
  }

  const lower = arg.toLowerCase();
  const norm = (s: unknown): string =>
    String(s || '')
      .toLowerCase()
      .replace(/\s*\(\d+\)\s*$/, '')
      .replace(/[\s_-]+/g, '-');
  const target = norm(arg);

  const idMatch = list.find((p) => p.id === arg);
  if (idMatch) return { id: idMatch.id, name: idMatch.name, source: 'id' as const };

  const exact = list.filter((p) => String(p.name || '').toLowerCase() === lower);
  if (exact.length === 1) { const p = exact[0]!; return { id: p.id, name: p.name, source: 'exact' as const }; }

  const slugged = list.filter((p) => norm(p.name) === target);
  if (slugged.length === 1) { const p = slugged[0]!; return { id: p.id, name: p.name, source: 'slug' as const }; }

View on GitHub (pinned to 5be4028344)

Solutions

  1. Create a project first via the Open Design UI or the project MCP/CLI tool, then retry.
  2. Confirm you are pointing at the right daemon and OD_DATA_DIR (check tools-dev status and namespace).
  3. If projects should exist, verify the data root the daemon resolved matches where they live.
  4. For imported-folder projects, confirm metadata.baseDir points at the imported location.

Example fix

// before: daemon has zero projects
runStart({ project: "anything" })
// after: create one first
await createProject({ title: "my-deck" });
runStart({ project: "my-deck" })
Defensive patterns

Strategy: validation

Validate before calling

const list = await fetchProjectList(baseUrl, headers);
if (list.length === 0) throw new Error('create a project before invoking run tools');

Prevention

When it happens

Trigger: Fresh daemon install with no projects created; all projects deleted; pointing at a data root (OD_DATA_DIR) that is empty or newly initialized; misconfigured namespace isolating an empty project set.

Common situations: First-time setup; CI using a clean OD_DATA_DIR; tools-dev --namespace pointing at an unused namespace; the user imported a folder but it registered under a different data root.

Related errors


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