risingwavelabs/risingwave · error · ExprError

null value in column

Error message

null value in column "{col_name}" of relation "{table_name}" violates not-null constraint

What it means

ExprError::NotNullViolation { col_name, table_name } is thrown when an expression evaluation (e.g. producing rows for insert/update) yields NULL for a column that carries a NOT NULL constraint. The message mirrors Postgres: 'null value in column "{col_name}" of relation "{table_name}" violates not-null constraint'. It names the offending column and table so the data problem can be located.

Solutions

  1. Wrap the projected expression in COALESCE with a sensible default for that column.
  2. Filter out rows where the constrained column would be NULL before writing.
  3. Relax the constraint (if acceptable) or backfill/repair the source data so NULLs no longer occur.

Example fix

// before
INSERT INTO users (id, nickname) SELECT id, nick FROM staging; -- nickname NOT NULL
// after
INSERT INTO users (id, nickname) SELECT id, COALESCE(nick, 'unknown') FROM staging;
Defensive patterns

Strategy: validation

Validate before calling

-- guard NOT NULL targets before insert
INSERT INTO users (id, nickname)
SELECT id, COALESCE(nick, 'unknown') FROM staging WHERE id IS NOT NULL;

Try / catch

// Extract col/table names for a data-quality alert
if let Some(ExprError::NotNullViolation { col_name, table_name }) = err.downcast_ref::<ExprError>() {
    alert(&format!("NULL in {table_name}.{col_name}"));
}

Prevention

When it happens

Trigger: INSERT/UPDATE (including sink/materialized-view writes driven by expressions) computing NULL for a NOT NULL column — e.g. a join missing rows, a cast producing NULL, or a projection passing NULL through to a constrained column.

Common situations: Left joins introducing NULLs before an insert, nullable upstream columns inserted into NOT NULL tables, default expressions returning NULL, schema migrations adding NOT NULL columns without backfill.

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 risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/28f91ce79db755ad. Report an issue: GitHub.

Appendix: source

Thrown at src/expr/core/src/error.rs:111

    Internal(
        #[from]
        #[backtrace]
        anyhow::Error,
    ),

    #[error("not a constant")]
    NotConstant,

    #[error("Context {0} not found")]
    Context(&'static str),

    #[error("field name must not be null")]
    FieldNameNull,

    #[error("too few arguments for format()")]
    TooFewArguments,

    #[error(
        "null value in column \"{col_name}\" of relation \"{table_name}\" violates not-null constraint"
    )]
    NotNullViolation {
        col_name: Box<str>,
        table_name: Box<str>,
    },

    #[error("invalid state: {0}")]
    InvalidState(String),

    /// Function error message returned by UDF.
    /// TODO: replace with `Function`
    #[error("{0}")]
    Custom(String),

    /// Error from a function call.
    ///
    /// Use [`ExprError::function`] to create this error.

View on GitHub (pinned to 6469eb736d)