{"record":{"id":"c3d3dd070db9f75a","repo":"Budibase/budibase","slug":"project-color-is-invalid","errorCode":null,"errorMessage":"Project color is invalid.","messagePattern":"Project color is invalid\\.","errorType":"validation","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/projects/crud.ts","lineNumber":38,"sourceCode":"  description?: string\n  color?: string\n}\n\ninterface UpdateProjectInput {\n  _id: string\n  _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","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/projects/crud.ts#L20-L56","documentation":"normaliseProjectColor wraps helpers.normaliseSafeCssColor; when the supplied color cannot be normalised to a safe CSS color it throws this 400 HTTPError. Used by project create and whenever an update includes a color property.","triggerScenarios":"create({ color: ... }) or update({ ..., color: ... }) with a value that is not a parseable CSS color — e.g. \"purple-ish\", \"#12345\" (bad hex length), empty string, arbitrary text, or unsafe formats the helper rejects.","commonSituations":"UI color pickers sending raw free-text input; API clients passing brand colors in unsupported formats; migration scripts copying color fields from other systems; sending null/empty string instead of omitting the field.","solutions":["Send a valid CSS color: hex (#ff0000), rgb()/rgba(), or a named CSS color","Omit the color field entirely to accept the default","Normalise on the client (e.g. parse to hex) before submitting","Check the value with a CSS color parser before calling the API"],"exampleFix":"// before\nawait sdk.projects.create({ name: \"Ops\", color: \"brand blue\" })\n// after\nawait sdk.projects.create({ name: \"Ops\", color: \"#0055ff\" })","handlingStrategy":"validation","validationCode":"const CSS_COLOR = /^(#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})|rgba?\\([^)]+\\)|[a-z]+)$/i\nif (color !== undefined && !CSS_COLOR.test(color)) throw new Error(\"Invalid color\")","typeGuard":"const isCssColor = (v: unknown): v is string =>\n  typeof v === \"string\" &&\n  (/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v) || /^rgba?\\(/i.test(v))","tryCatchPattern":"try {\n  await sdk.projects.create({ name, color })\n} catch (e) {\n  if (String(e.message).includes(\"color is invalid\")) {\n    await sdk.projects.create({ name }) // retry without color\n  }\n}","preventionTips":["Use a color picker that emits hex values, not free text","Normalise colors to #rrggbb on the client before submitting","Omit the color field when no color is chosen"],"tags":["validation","http-400","color","css"],"backgroundTag":"invalid-color-value","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}