{"record":{"id":"ec616046c2b4a806","repo":"Budibase/budibase","slug":"project-id-is-required","errorCode":null,"errorMessage":"Project id is required.","messagePattern":"Project id is required\\.","errorType":"validation","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/projects/crud.ts","lineNumber":95,"sourceCode":"  const now = new Date().toISOString()\n\n  const response = await db.put(\n    {\n      ...project,\n      color: normaliseProjectColor(project.color),\n      _id: docIds.generateProjectID(),\n      createdAt: now,\n      updatedAt: now,\n    },\n    { returnDoc: true }\n  )\n\n  return response.doc\n}\n\nexport async function update(project: UpdateProjectInput): Promise<Project> {\n  if (!project._id) {\n    throw new HTTPError(\"Project id is required.\", 400)\n  }\n  if (!project._rev) {\n    throw new HTTPError(\"Project revision is required.\", 400)\n  }\n  if (Object.hasOwn(project, \"name\")) {\n    validateProjectName(project.name)\n  }\n\n  const db = context.getWorkspaceDB()\n  const persisted = await get(project._id)\n  if (!persisted) {\n    throw new HTTPError(`Project with id '${project._id}' not found.`, 404)\n  }\n\n  const response = await db.put(\n    {\n      ...persisted,\n      ...project,","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/projects/crud.ts#L77-L113","documentation":"update() requires the _id of the project being modified; calling it without _id throws this 400 HTTPError before any validation or DB access. The SDK expects a full UpdateProjectInput with identity fields present.","triggerScenarios":"sdk.projects.update({ _rev, name }) with _id undefined/null/empty — usually a destructuring bug, an optional-chained id that was undefined, or constructing the payload from a failed fetch.","commonSituations":"Client code reading project._id from a list row that was never hydrated; responses from another API shape lacking _id; TypeScript suppressed so an undefined id slipped through.","solutions":["Populate _id from the persisted project before calling update","Guard the call: if (!project._id) throw/return before invoking the SDK","Verify the object you spread into the update payload actually contains _id","Re-fetch the project (sdk.projects.get / fetch) to obtain its _id"],"exampleFix":"// before\nawait sdk.projects.update({ _rev: project._rev, name: \"New\" })\n// after\nawait sdk.projects.update({ _id: project._id!, _rev: project._rev, name: \"New\" })","handlingStrategy":"type-guard","validationCode":"const hasId = (p: { _id?: string }): p is { _id: string } =>\n  typeof p._id === \"string\" && p._id.length > 0\nif (!hasId(payload)) throw new Error(\"Missing project _id\")\nawait sdk.projects.update(payload)","typeGuard":"const hasProjectId = (p: { _id?: string }): p is { _id: string } =>\n  typeof p._id === \"string\" && p._id.length > 0","tryCatchPattern":"try {\n  await sdk.projects.update(payload as { _id: string; _rev: string })\n} catch (e) {\n  if (String(e.message).includes(\"id is required\")) {\n    // re-fetch the project to recover its _id\n  }\n}","preventionTips":["Always build update payloads from a fetched Project object","Don't destructure _id from possibly-unhydrated list rows","Let TypeScript strictness flag optional _id before calling update"],"tags":["validation","http-400","required-field","update"],"backgroundTag":"missing-required-field","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}