nocodb/nocodb · error · Error

Missing required columns: ${[...missingRequiredColumns].join

Error message

Missing required columns: ${[...missingRequiredColumns].join(', ')}

What it means

getDataInsertObj in dataUtils reduces the row over meta.columns and accumulates any required column whose value is null/empty into missingRequiredColumns. When throwError is true and that set is non-empty, it throws 'Missing required columns: <names>' so the caller knows the row violates NOT NULL constraints before any API insert.

Source

Thrown at packages/nc-gui/utils/dataUtils.ts:217

          o[childCol.title!] = ltarVal[relatedTableMeta!.columns!.find((c) => c.id === colOpt.fk_parent_column_id)!.title!]
          if (o[childCol.title!] !== null && o[childCol.title!] !== undefined) missingRequiredColumns.delete(childCol.title)
        }
      }
    }
    // check all the required columns are not null
    if (isColumnRequiredAndNull(col, row)) {
      missingRequiredColumns.add(col.title)
    }

    if (!col.ai && (row?.[col.title as string] !== null || allowNullFieldIds.includes(col.id as string))) {
      o[col.title as string] = row?.[col.title as string]
    }

    return o
  }, Promise.resolve({}))

  if (throwError && missingRequiredColumns.size) {
    throw new Error(`Missing required columns: ${[...missingRequiredColumns].join(', ')}`)
  }

  return { missingRequiredColumns, insertObj }
}

// Relation types whose linked record can belong to only ONE parent record.
// Copying such a link onto a duplicated record REASSIGNS the linked record to the
// copy and silently detaches it from the original — a data-integrity hazard.
//  - has-many / one-to-many: the related rows carry the FK pointing here, so
//    copying moves those rows onto the duplicate.
//  - one-to-one: a single record on each side, so copying steals it.
// belongs-to / many-to-one own their own FK (the parent keeps its other children)
// and many-to-many is additive, so those relationships copy safely.
const SINGLE_PARENT_RELATION_TYPES: RelationTypes[] = [
  RelationTypes.HAS_MANY,
  RelationTypes.ONE_TO_ONE,
  RelationTypes.ONE_TO_MANY,
]

View on GitHub (pinned to d3caaf4e89)

Solutions

  1. Pre-validate the row against meta.columns: fill or prompt for every required column before insert.
  2. Call getDataInsertObj with throwError=false first to collect missingRequiredColumns and show inline field errors.
  3. For duplicates, copy the source row's required values so the new row is never missing them.
  4. Ensure belongs-to relations include a valid linked record when the FK column is required.

Example fix

// before
const { insertObj } = await getDataInsertObj({ ...row, throwError: true })
// after
const { missingRequiredColumns, insertObj } = await getDataInsertObj({ ...row, throwError: false })
if (missingRequiredColumns.size) {
  showFieldErrors([...missingRequiredColumns])
  return
}
Defensive patterns

Strategy: validation

Validate before calling

// Run with throwError=false first to collect missing fields
const { missingRequiredColumns, insertObj } = await getDataInsertObj({ ...args, throwError: false })
if (missingRequiredColumns.size) {
  showFieldErrors([...missingRequiredColumns])
  return
}
await insertRow(insertObj)

Type guard

const rowSatisfiesRequired = (row: Record<string, any>, required: string[]): boolean =>
  required.every((title) => row?.[title] !== undefined && row?.[title] !== null && row?.[title] !== '')

Try / catch

try {
  await getDataInsertObj({ ...args, throwError: true })
} catch (e) {
  if ((e as Error).message.startsWith('Missing required columns:')) {
    const missing = (e as Error).message.replace('Missing required columns: ', '').split(', ')
    showFieldErrors(missing)
  } else throw e
}

Prevention

When it happens

Trigger: Inserting or duplicating a row where one or more required (NOT NULL, no default, non-auto-increment) columns were left empty, with throwError=true. Belongs-to relations whose FK is required also land in the set when the linked value is absent.

Common situations: Form submissions missing mandatory fields; duplication of a partial row; bulk paste/import that skips required columns; LTAR belongs-to fields not populated; columns whose rqd flag is true server-side.

Related errors


AI-assisted analysis of nocodb/nocodb@d3caaf4e89 (2026-08-12). Data as JSON: /api/errors/18fa04263f61a6ee. Report an issue: GitHub.