{"record":{"id":"d938f591bb155866","repo":"nexu-io/open-design","slug":"project-arg-omitted-and-open-design-has-no-active","errorCode":null,"errorMessage":"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>\".","messagePattern":"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>\"\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"apps/daemon/src/mcp.ts","lineNumber":2951,"sourceCode":"async function resolveProjectArg(\n  baseUrl: string,\n  arg: unknown,\n  headers?: Record<string, string>,\n): Promise<{ id: string; resolved: ResolvedProject | null; active: ActiveContext | null }> {\n  if (typeof arg === 'string' && arg.length > 0) {\n    const resolved = await resolveProjectId(baseUrl, arg, headers);\n    return { id: resolved.id, resolved, active: null };\n  }\n  let active: ActiveContext;\n  try {\n    active = await getJson<ActiveContext>(`${baseUrl}/api/active`);\n  } catch (err) {\n    throw new Error(\n      `project arg omitted and active context lookup failed: ${errorMessage(err)}. Pass project=\"<id-or-name>\".`,\n    );\n  }\n  if (!active || active.active === false || !active.projectId) {\n    throw new Error(\n      '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>\".',\n    );\n  }\n  return { id: active.projectId, resolved: null, active };\n}\n\nasync function resolveProjectId(\n  baseUrl: string,\n  arg: unknown,\n  headers?: Record<string, string>,\n): Promise<ResolvedProject> {\n  if (typeof arg !== 'string' || !arg) {\n    throw new Error('project is required (string).');\n  }\n  if (UUID_RE.test(arg)) return { id: arg, name: arg, source: 'uuid' as const };\n\n  const list = await fetchProjectList(baseUrl, headers);\n  if (list.length === 0) {","sourceCodeStart":2933,"sourceCodeEnd":2969,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/mcp.ts#L2933-L2969","documentation":"Thrown by resolveProjectArg when GET /api/active succeeded but returned `active === false` or no `projectId`. The active context is a short-lived pointer to the project the user last interacted with in the Open Design UI, and it expires about 5 minutes after the last interaction. The MCP layer cannot guess which project to target without it.","triggerScenarios":"User closed or backgrounded Open Design for >5 min then invoked an MCP tool without `project`; fresh daemon where the user never opened a project; UI session expired; user switched projects but the active pointer lagged.","commonSituations":"Long-running agent tasks that outlive the active window; CI/headless runs with no UI user present; the user clicked away from the Open Design window.","solutions":["Pass `project: \"<id-or-name>\"` explicitly so the call does not depend on UI activity.","Have the user click into a project in the Open Design UI to refresh the active pointer, then retry.","For automation/CI, always supply project explicitly and never rely on the active context.","List projects first via the project MCP tool to discover the id, then pass it."],"exampleFix":"// before\nrunStart({ prompt })  // relies on active context, expired\n// after\nrunStart({ prompt, project: \"my-deck\" })","handlingStrategy":"validation","validationCode":"async function ensureActive(baseUrl: string): Promise<string> {\n  const a = await getJson(`${baseUrl}/api/active`);\n  if (!a || a.active === false || !a.projectId) throw new Error('no active project; pass project explicitly');\n  return a.projectId;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runStart({ prompt });\n} catch (e) {\n  if (String(e.message).includes('no active project')) {\n    await runStart({ prompt, project: await pickProject() });\n  } else throw e;\n}","preventionTips":["Never rely on the active context for unattended runs.","Pass project explicitly whenever the user may be away.","Refresh the active pointer by interacting with the UI before short interactive sessions."],"tags":["mcp","project-resolution","active-context","session"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}