Budibase/budibase · error · HTTPError

Cannot make field "${key}" required, it has a default value.

Error message

Cannot make field "${key}" required, it has a default value.

What it means

Budibase forbids a table field from being both required and carrying a default value, because the semantics conflict (a default would satisfy validation, making required meaningless). checkDefaultFields runs on every table save via guardTable and returns HTTP 400 when a schema field has a non-null default and required constraints.

Source

Thrown at packages/server/src/api/controllers/table/index.ts:81

import { getRowParams } from "../../../db/utils"

function pickApi({ tableId, table }: { tableId?: string; table?: Table }) {
  if (table && isExternalTable(table)) {
    return external
  }
  if (tableId && isExternalTableID(tableId)) {
    return external
  }
  return internal
}

function checkDefaultFields(table: Table) {
  for (const [key, field] of Object.entries(table.schema)) {
    if (!("default" in field) || field.default == null) {
      continue
    }
    if (helpers.schema.isRequired(field.constraints)) {
      throw new HTTPError(
        `Cannot make field "${key}" required, it has a default value.`,
        400
      )
    }
  }
}

function stripIgnoreTimezoneSuffix(rows: Row[], table: Table): Row[] {
  const columns = Object.entries(table.schema)
    .filter(
      ([_, schema]) =>
        schema.type === FieldType.DATETIME &&
        schema.ignoreTimezones &&
        !schema.timeOnly
    )
    .map(([name]) => name)
  if (!columns.length) {
    return rows

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Remove the "default" key from the field schema if the field must be required
  2. Drop the required constraint (set constraints.presence.required to false) if the default should be kept
  3. Re-save through the Builder UI which enforces the mutual exclusion interactively

Example fix

// before
schema: { status: { type: "string", constraints: { presence: { required: true } }, default: "draft" } }
// after
schema: { status: { type: "string", constraints: { presence: { required: true } } } }
Defensive patterns

Strategy: validation

Validate before calling

function fieldHasConflict(field) {
  const hasDefault = field != null && "default" in field && field.default != null
  const isRequired = field?.constraints?.presence?.required === true
  return hasDefault && isRequired
}
for (const key of Object.keys(table.schema)) {
  if (fieldHasConflict(table.schema[key])) throw new Error(`field ${key}: required + default conflict`)
}

Type guard

const hasDefaultAndRequired = (f) => f != null && "default" in f && f.default != null && f?.constraints?.presence?.required === true

Try / catch

try {
  await api.saveTable(table)
} catch (e) {
  if (e?.status === 400 && /required, it has a default value/.test(e.message)) {
    const key = e.message.match(/field \"(.+?)\"/)?.[1]
    // strip default or required for that key and retry
  } else throw e
}

Prevention

When it happens

Trigger: Saving a table (POST/PUT to table API) whose schema contains a field with both a "default" value and constraints indicating required (helpers.schema.isRequired true).

Common situations: Builder UI or automation scripts marking a column required after a default was set; imported table definitions with both properties; API clients constructing schema JSON by hand.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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