Budibase/budibase · error · HTTPError

Project color is invalid.

Error message

Project color is invalid.

What it means

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.

Source

Thrown at packages/server/src/sdk/workspace/projects/crud.ts:38

  description?: string
  color?: string
}

interface UpdateProjectInput {
  _id: string
  _rev: string
  name?: string
  description?: string
  color?: string
}

type Rollback = () => Promise<void>

const normaliseProjectColor = (color?: string) => {
  try {
    return helpers.normaliseSafeCssColor(color)
  } catch {
    throw new HTTPError("Project color is invalid.", 400)
  }
}

const validateProjectName = (name?: string) => {
  if (typeof name !== "string" || !name.trim()) {
    throw new HTTPError("Project name is required.", 400)
  }
}

const isProjectId = (id?: string) =>
  id?.startsWith(prefixed(DocumentType.PROJECT))

export async function fetch(): Promise<Project[]> {
  const db = context.getWorkspaceDB()
  const docs = await db.allDocs<Project>(
    docIds.getProjectParams(null, { include_docs: true })
  )

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Send a valid CSS color: hex (#ff0000), rgb()/rgba(), or a named CSS color
  2. Omit the color field entirely to accept the default
  3. Normalise on the client (e.g. parse to hex) before submitting
  4. Check the value with a CSS color parser before calling the API

Example fix

// before
await sdk.projects.create({ name: "Ops", color: "brand blue" })
// after
await sdk.projects.create({ name: "Ops", color: "#0055ff" })
Defensive patterns

Strategy: validation

Validate before calling

const CSS_COLOR = /^(#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})|rgba?\([^)]+\)|[a-z]+)$/i
if (color !== undefined && !CSS_COLOR.test(color)) throw new Error("Invalid color")

Type guard

const isCssColor = (v: unknown): v is string =>
  typeof v === "string" &&
  (/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(v) || /^rgba?\(/i.test(v))

Try / catch

try {
  await sdk.projects.create({ name, color })
} catch (e) {
  if (String(e.message).includes("color is invalid")) {
    await sdk.projects.create({ name }) // retry without color
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/c3d3dd070db9f75a. Report an issue: GitHub.