{"record":{"id":"cf8303e71de74c91","repo":"nexu-io/open-design","slug":"project-not-found-projectid","errorCode":null,"errorMessage":"project not found: ${projectId}","messagePattern":"project not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/design/finalize-design.ts","lineNumber":274,"sourceCode":"      manifest: newest.artifactManifest ?? null,\n    };\n  }\n\n  return null;\n}\n\nexport async function finalizeDesignPackage(\n  db: Db,\n  projectsRoot: string,\n  designSystemsRoot: string,\n  projectId: string,\n  options: FinalizeOptions,\n): Promise<FinalizeAnthropicResponse> {\n  const project = getProject(db, projectId);\n  if (!project) {\n    // Defensive — the route handler validates this and returns 404 before\n    // reaching here. Kept for direct (non-HTTP) callers, e.g. CLI scripts.\n    throw new Error(`project not found: ${projectId}`);\n  }\n\n  // Imported-folder projects (created via /api/import/folder) carry\n  // `metadata.baseDir` and write to the user's actual folder rather than\n  // `.od/projects/<id>`. resolveProjectDir handles both shapes; calling\n  // bare `projectDir` would silently land DESIGN.md in the hidden daemon\n  // data dir for these projects (PR #832 P1 finding from @lefarcen).\n  const projectMetadata = (project as { metadata?: { baseDir?: string } | null }).metadata ?? null;\n  const dir = resolveProjectDir(projectsRoot, projectId, projectMetadata ?? undefined);\n  // For imported-folder projects, `dir` is the user's own directory and\n  // already exists; mkdirSync is a no-op (recursive:true is idempotent).\n  // For native projects, it lazily creates `.od/projects/<id>`.\n  fs.mkdirSync(dir, { recursive: true });\n  const finalPath = path.join(dir, OUTPUT_FILENAME);\n  const lockPath = path.join(dir, LOCK_FILENAME);\n  const tmpPath = path.join(\n    dir,\n    `${OUTPUT_FILENAME}.tmp.${process.pid}.${randomBytes(4).toString('hex')}`,","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/design/finalize-design.ts#L256-L292","documentation":"getProject(db, projectId) returned null inside finalizeDesignPackage. This is defensive: the route handler validates the project exists and returns 404 before reaching this function. It is retained for direct (non-HTTP) callers such as CLI scripts. When reached, it surfaces as a generic Error which the route maps to 500 INTERNAL_ERROR.","triggerScenarios":"Calling finalizeDesignPackage directly (not via the HTTP route) with a projectId that has no row in the projects table; or a race where the project was deleted between the route's existence check and the call.","commonSituations":"A CLI/automation script referencing a deleted or mistyped project ID; a stale project ID cached client-side; the project was removed in another tab between the 404 pre-check and the call (rare).","solutions":["Verify the project exists with getProject(db, projectId) before calling finalizeDesignPackage.","Prefer the HTTP endpoint POST /api/projects/:id/finalize, which validates existence and returns 404 cleanly.","Re-check the projectId spelling / source if it came from a stale cache."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm the project exists before calling finalizeDesignPackage directly.\nimport { getProject } from '../db.js';\nif (!getProject(db, projectId)) {\n  throw new Error(`project not found: ${projectId}`);\n}\nconst result = await finalizeDesignPackage(db, projectsRoot, dsRoot, projectId, options);","typeGuard":"function projectExists(db: Db, id: string): boolean {\n  return getProject(db, id) !== null;\n}","tryCatchPattern":"try {\n  await finalizeDesignPackage(db, projectsRoot, dsRoot, projectId, options);\n} catch (err) {\n  if (String(err).startsWith('project not found:')) {\n    // direct (non-HTTP) caller: surface a clean 404-equivalent\n  }\n  throw err;\n}","preventionTips":["Prefer the HTTP finalize endpoint, which returns a clean 404 before reaching this code.","For CLI/automation, fetch and validate the project row first.","Refresh cached project IDs after deletions."],"tags":["finalize","project","not-found","validation"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}