{"record":{"id":"8dd5d77509b97407","repo":"risingwavelabs/risingwave","slug":"multiple-errors-1","errorCode":null,"errorMessage":"multiple errors:\n{1}","messagePattern":"multiple errors:\n(.+?)","errorType":"exception","errorClass":"ExprError","httpStatus":null,"severity":"error","filePath":"src/expr/core/src/error.rs","lineNumber":44,"sourceCode":"pub struct ContextUnavailable(&'static str);\n\nimpl ContextUnavailable {\n    pub fn new(field: &'static str) -> Self {\n        Self(field)\n    }\n}\n\nimpl From<ContextUnavailable> for ExprError {\n    fn from(e: ContextUnavailable) -> Self {\n        ExprError::Context(e.0)\n    }\n}\n\n/// The error type for expression operations.\n#[derive(Error, ReportDebug)]\npub enum ExprError {\n    /// A collection of multiple errors in batch evaluation.\n    #[error(\"multiple errors:\\n{1}\")]\n    Multiple(ArrayRef, MultiExprError),\n\n    // Ideally \"Unsupported\" errors are caught by frontend. But when the match arms between\n    // frontend and backend are inconsistent, we do not panic with `unreachable!`.\n    #[error(\"Unsupported function: {0}\")]\n    UnsupportedFunction(String),\n\n    #[error(\"Unsupported cast: {0} to {1}\")]\n    UnsupportedCast(DataType, DataType),\n\n    #[error(\"Casting to {0} out of range\")]\n    CastOutOfRange(&'static str),\n\n    #[error(\"Numeric out of range\")]\n    NumericOutOfRange,\n\n    #[error(\"Numeric out of range: underflow\")]\n    NumericUnderflow,","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/core/src/error.rs#L26-L62","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nSELECT col::int FROM t; -- multiple invalid rows\n// after\nSELECT try_cast(col as int) FROM t;","handlingStrategy":"try-catch","validationCode":"// validate inputs before batch evaluation\nlet ok = rows.iter().all(|r| can_cast(r, target_type));","typeGuard":null,"tryCatchPattern":"match expr.eval(batch).await {\n    Err(e) if matches!(e.root_cause(), _) || e.to_string().starts_with(\"multiple errors:\") => {\n        // parse inner per-row errors, fall back to row-wise evaluation\n    }\n    other => other?,\n}","preventionTips":["Prefer try_cast/nullif for dirty data tolerance","Run data quality checks upstream","Fail-fast per row in critical pipelines instead of batch"],"tags":["batch-evaluation","vectorization","rust","expression"],"backgroundTag":"internal-invariant-violation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}