error: null value in column "total" of relation "orders" violates not-null constraint

Node.js · updated 2026-11-10

Raised by Postgres (SQLSTATE 23502) when an INSERT or UPDATE would store null in a column declared NOT NULL, either because the value was null or because the column was left out and has no default. node-postgres throws it with error.column and error.table set, psycopg raises NotNullViolation, Django and SQLAlchemy wrap it as IntegrityError.

error: null value in column "total" of relation "orders" violates not-null constraint
    at node_modules/pg/lib/client.js:694:17
    at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
  code: '23502', column: 'total', table: 'orders'
  detail: 'Failing row contains (2, 11111111-1111-1111-1111-111111111111, null).'

Quick fix

Read which column is named and the DETAIL row, then find why the code sent nothing for it: a field missing from the request body, a renamed property, an undefined variable (node-postgres sends undefined as null), or a column added as NOT NULL without a default. Validate the input before the insert, or give the column a sensible default.

  1. Note the column and table in the message; error.column and error.table carry them in node-postgres.
  2. Read the DETAIL line: the failing row in column order shows which values did arrive.
  3. Trace the value back: the request body, the form field name, the ORM model. An undefined parameter becomes null.
  4. Validate required fields at the API edge and return a 400 that names the field, instead of letting the database fail.
  5. If the value has a natural default (a timestamp, false, 0), set it on the column: alter table orders alter column total set default 0.

Why it happens

The field never arrived

The client stopped sending it, sent it under another name, or the form left it empty, and nothing validated the body.

undefined becomes null

node-postgres sends an undefined parameter as null, so a typo in a property name reaches the database as a null value.

Column added without a default

A migration added a NOT NULL column, and code that inserts without it (old clients, background jobs) now fails.

Partial update overwrote the value

An UPDATE that sets every column from a partial object writes null into the ones it did not have.

Other fixes

  • For a NOT NULL column added to a table with rows, add it with a default, or add it nullable, backfill, then set NOT NULL.
  • Validate with a schema (zod, pydantic) before the query so the user gets a field error instead of a 500.

Same error, other wording

  • psycopg.errors.NotNullViolation: null value in column "email" of relation "users" violates not-null constraint
  • null value in column "total" violates not-null constraint (PostgreSQL 12 and older)
  • django.db.utils.IntegrityError: null value in column "user_id" of relation "app_order" violates not-null constraint

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and, when you set it, the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the not-null constraint errors, group them by table and column, trace where each missing value should have come from, and add validation or a default so the request fails cleanly or succeeds.

Setup for Node.js and Express or Vercel Functions, then have your agent fix and resolve it.

Related errors

More in Databases

References: PostgreSQL docs: constraints (not-null, foreign keys), PostgreSQL docs: error codes (23502 not_null_violation)

Spotted a mistake? Email hello@greatwork.company. About Runheed.