{"record":{"id":"0e90af89ddce98b3","repo":"Budibase/budibase","slug":"project-name-is-required","errorCode":null,"errorMessage":"Project name is required.","messagePattern":"Project name is required\\.","errorType":"validation","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/projects/crud.ts","lineNumber":44,"sourceCode":"  _rev: string\n  name?: string\n  description?: string\n  color?: string\n}\n\ntype Rollback = () => Promise<void>\n\nconst normaliseProjectColor = (color?: string) => {\n  try {\n    return helpers.normaliseSafeCssColor(color)\n  } catch {\n    throw new HTTPError(\"Project color is invalid.\", 400)\n  }\n}\n\nconst validateProjectName = (name?: string) => {\n  if (typeof name !== \"string\" || !name.trim()) {\n    throw new HTTPError(\"Project name is required.\", 400)\n  }\n}\n\nconst isProjectId = (id?: string) =>\n  id?.startsWith(prefixed(DocumentType.PROJECT))\n\nexport async function fetch(): Promise<Project[]> {\n  const db = context.getWorkspaceDB()\n  const docs = await db.allDocs<Project>(\n    docIds.getProjectParams(null, { include_docs: true })\n  )\n\n  return docs.rows\n    .map(row => row.doc)\n    .filter((doc): doc is Project => !!doc)\n    .sort((a, b) => a.name.localeCompare(b.name))\n}\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/projects/crud.ts#L26-L62","documentation":"validateProjectName rejects any name that is not a non-empty, non-whitespace string. Called unconditionally by create and conditionally by update (when a name property is present), throwing this 400 HTTPError.","triggerScenarios":"create({ name: undefined }) or name: \"\" or \"   \"; update({ _id, _rev, name: \"\" }) — sending the name key with an empty value triggers validation even though name is optional in updates.","commonSituations":"Forms allowing blank submission; API clients sending name: \"\" to 'clear' a name (not supported); destructuring payloads where name is absent on create; whitespace-only input passing a naive required check.","solutions":["Provide a non-empty trimmed name string when creating a project","On update, omit the name property entirely rather than sending an empty value","Trim client-side and require the field in your form before submitting","Check payload construction for undefined values leaking into name"],"exampleFix":"// before\nawait sdk.projects.update({ _id, _rev, name: \"\" })\n// after\nawait sdk.projects.update({ _id, _rev }) // omit name, or pass a real name","handlingStrategy":"validation","validationCode":"const nameIsValid = (n: unknown): n is string =>\n  typeof n === \"string\" && n.trim().length > 0\nif (!nameIsValid(input.name)) throw new Error(\"Project name is required\")","typeGuard":"const hasName = (v: unknown): v is { name: string } =>\n  typeof v === \"object\" && v !== null && \"name\" in v &&\n  typeof (v as { name: unknown }).name === \"string\" && (v as { name: string }).name.trim() !== \"\"","tryCatchPattern":"try {\n  await sdk.projects.create({ name })\n} catch (e) {\n  if (String(e.message).includes(\"name is required\")) {\n    // surface a required-field error to the user\n  }\n}","preventionTips":["Make name a required field in forms; trim before submit","On update, omit name instead of sending an empty string","Trim whitespace-only names client-side"],"tags":["validation","http-400","required-field"],"backgroundTag":"missing-required-field","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}