risingwavelabs/risingwave · error · ExprError
multiple errors: {1}
Error message
multiple errors:
{1} What it means
ExprError::Multiple wraps an array of per-row error values accumulated during batch (vectorized) expression evaluation. When several rows fail, the library collects the error strings into a MultiExprError and reports them together with the offending ArrayRef.
Source
Thrown at src/expr/core/src/error.rs:44
pub struct ContextUnavailable(&'static str);
impl ContextUnavailable {
pub fn new(field: &'static str) -> Self {
Self(field)
}
}
impl From<ContextUnavailable> for ExprError {
fn from(e: ContextUnavailable) -> Self {
ExprError::Context(e.0)
}
}
/// The error type for expression operations.
#[derive(Error, ReportDebug)]
pub enum ExprError {
/// A collection of multiple errors in batch evaluation.
#[error("multiple errors:\n{1}")]
Multiple(ArrayRef, MultiExprError),
// Ideally "Unsupported" errors are caught by frontend. But when the match arms between
// frontend and backend are inconsistent, we do not panic with `unreachable!`.
#[error("Unsupported function: {0}")]
UnsupportedFunction(String),
#[error("Unsupported cast: {0} to {1}")]
UnsupportedCast(DataType, DataType),
#[error("Casting to {0} out of range")]
CastOutOfRange(&'static str),
#[error("Numeric out of range")]
NumericOutOfRange,
#[error("Numeric out of range: underflow")]
NumericUnderflow,View on GitHub (pinned to 6469eb736d)
Solutions
- Read the inner error strings in the message to find which rows/values failed
- Clean or filter invalid input rows before evaluation
- Use per-row fallbacks (e.g. try_cast, nullif) to avoid hard failures
- Add data quality checks upstream in the ingestion pipeline
Example fix
// before SELECT col::int FROM t; -- multiple invalid rows // after SELECT try_cast(col as int) FROM t;
Defensive patterns
Strategy: try-catch
Validate before calling
// validate inputs before batch evaluation let ok = rows.iter().all(|r| can_cast(r, target_type));
Try / catch
match expr.eval(batch).await {
Err(e) if matches!(e.root_cause(), _) || e.to_string().starts_with("multiple errors:") => {
// parse inner per-row errors, fall back to row-wise evaluation
}
other => other?,
} Prevention
- Prefer try_cast/nullif for dirty data tolerance
- Run data quality checks upstream
- Fail-fast per row in critical pipelines instead of batch
When it happens
Trigger: Batch evaluation of an expression (e.g. cast, div) where multiple rows produce errors; the evaluator aggregates row errors into MultiExprError and constructs ExprError::Multiple.
Common situations: Casting a column with several invalid values; division by zero in multiple rows of a batch query; running queries over materialized views containing dirty data.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Expr error: {0}
- Unsupported cast: {0} to {1}
- Casting to {0} out of range
- Expression error: {0}
- query_epoch not set in distributed lookup join
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/8dd5d77509b97407.
Report an issue: GitHub.