{"record":{"id":"e821bf17a3c4cc1a","repo":"nexu-io/open-design","slug":"project-projectid-not-found","errorCode":null,"errorMessage":"Project ${projectId} not found","messagePattern":"Project (.+?) not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/collab/project-share-dir.ts","lineNumber":7,"sourceCode":"export function resolveProjectShareDir(\n  projectsRoot: string,\n  projectId: string,\n  project: { id: string; metadata?: unknown } | null | undefined,\n  resolveProjectDir: (projectsRoot: string, projectId: string, metadata?: unknown) => string,\n): string {\n  if (!project) throw new Error(`Project ${projectId} not found`);\n  return resolveProjectDir(projectsRoot, projectId, project.metadata);\n}\n","sourceCodeStart":1,"sourceCodeEnd":10,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/collab/project-share-dir.ts#L1-L10","documentation":"Thrown by resolveProjectShareDir when the `project` argument is null or undefined. The function resolves a project's share directory by delegating to resolveProjectDir with the project's metadata, so it needs an actual project object; a missing project is treated as a programmer error rather than silently producing a path. The projectId is echoed for diagnostics.","triggerScenarios":"A caller that looked up a project by id, got null back (not found / deleted), and then passed that null straight into resolveProjectShareDir.","commonSituations":"A race where the project is deleted between the lookup and the share-dir resolution, a wrong/mistyped project id, or a caller that forgot to handle the not-found case from its own lookup.","solutions":["Handle the not-found case at the lookup site before calling resolveProjectShareDir.","Verify the projectId is correct and the project still exists.","Return a 404 or equivalent upstream instead of forwarding a null project to this function."],"exampleFix":"// before\nconst project = await findProject(id);\nconst dir = resolveProjectShareDir(root, id, project, resolveDir);\n// after\nconst project = await findProject(id);\nif (!project) throw new NotFoundError(`project ${id} not found`);\nconst dir = resolveProjectShareDir(root, id, project, resolveDir);","handlingStrategy":"validation","validationCode":"function ensureProjectThenShareDir(projectsRoot, projectId, lookup, resolveProjectDir) {\n  const project = lookup(projectId);\n  if (!project) throw new Error(`Project ${projectId} not found`);\n  return resolveProjectShareDir(projectsRoot, projectId, project, resolveProjectDir);\n}","typeGuard":"function hasProject(value: unknown): value is { id: string; metadata?: unknown } {\n  return Boolean(value) && typeof value === 'object' && typeof (value as { id?: unknown }).id === 'string';\n}","tryCatchPattern":"try {\n  return resolveProjectShareDir(root, projectId, project, resolveDir);\n} catch (err) {\n  if (err instanceof Error && /Project .* not found/.test(err.message)) {\n    // return 404 upstream instead of crashing the request\n  }\n  throw err;\n}","preventionTips":["Always null-check the project lookup result before resolving its share dir.","Handle not-found at the route boundary with a proper 404.","Beware races: re-validate existence if the project may have been deleted concurrently."],"tags":["project","validation","collab","share"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}