Budibase/budibase · error · HTTPError

You can't hide "${field.name}" because it is a required fiel

Error message

You can't hide "${field.name}" because it is a required field.

What it means

checkRequiredFields walks table fields with constraints (required) and refuses to let a view hide them: if the field exists in the view schema with visible falsy, a 400 HTTPError is thrown. Required columns must stay visible so users can supply their values.

Source

Thrown at packages/server/src/sdk/workspace/views/index.ts:308

function checkRequiredFields(
  table: Table,
  view: Omit<ViewV2, "id" | "version">
) {
  const existingView = table.views?.[view.name] as ViewV2 | undefined
  for (const field of Object.values(table.schema)) {
    if (!helpers.schema.isRequired(field.constraints)) {
      continue
    }

    const viewSchemaField = view.schema?.[field.name]
    const existingViewSchema = existingView?.schema?.[field.name]
    if (!viewSchemaField && !existingViewSchema?.visible) {
      // Supporting existing configs with required columns but hidden in views
      continue
    }

    if (!viewSchemaField?.visible) {
      throw new HTTPError(
        `You can't hide "${field.name}" because it is a required field.`,
        400
      )
    }

    if (
      helpers.views.isBasicViewField(viewSchemaField) &&
      viewSchemaField.readonly
    ) {
      throw new HTTPError(
        `You can't make "${field.name}" readonly because it is a required field.`,
        400
      )
    }
  }
}

export async function create(

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Set visible: true for the required field in the view schema.
  2. Remove the required constraint from the table field if hiding it is genuinely needed.
  3. Remove the field from the view schema only if the legacy continue branch applies (field absent and not previously visible) — otherwise this won't bypass the check.

Example fix

// before
view.schema["title"].visible = false // title is required in table
// after
view.schema["title"].visible = true
Defensive patterns

Strategy: validation

Validate before calling

for (const f of Object.keys(table.schema)) {
  if (table.schema[f].constraints?.required && view.schema?.[f] && view.schema[f].visible !== true) {
    view.schema[f].visible = true
  }
}

Type guard

function requiredFieldsVisible(view: ViewV2, table: Table): boolean {
  return Object.entries(table.schema).every(([name, f]) =>
    !(f.constraints?.required && view.schema?.[name] && view.schema[name].visible !== true))
}

Try / catch

try {
  await sdk.views.update(view)
} catch (e) {
  if (e instanceof HTTPError && e.status === 400 && e.message.includes("because it is a required field")) {
    // make the field visible or drop the required constraint, then retry
  } else { throw e }
}

Prevention

When it happens

Trigger: create/update via guardViewSchema where a required table field maps to viewSchema[field] with visible !== true (and the field isn't in the legacy hidden-but-required escape hatch branch).

Common situations: Hiding required columns in the builder; bulk visibility toggles; view JSON edited by hand or migrated between apps where required flags changed.

Related errors


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