{"record":{"id":"1c75b4b6f258fd71","repo":"risingwavelabs/risingwave","slug":"failed-to-evaluate-the-input-for-fallback-arm","errorCode":null,"errorMessage":"failed to evaluate the input for fallback arm","messagePattern":"failed to evaluate the input for fallback arm","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/impl/src/scalar/case.rs","lineNumber":179,"sourceCode":"            return_type,\n            arms,\n            fallback,\n            operand,\n        }\n    }\n}\n\nimpl<E: ExpressionInfo> ExpressionInfo for ConstantLookupExpression<E> {\n    fn return_type(&self) -> DataType {\n        self.return_type.clone()\n    }\n}\n\nmacro_rules! eval_fallback_lookup {\n    ($mode:ident, $this:expr, $input:expr) => {{\n        if let Some(ref fallback) = $this.fallback {\n            let Ok(res) = risingwave_expr::forward!($mode, fallback, eval_row($input)) else {\n                bail!(\"failed to evaluate the input for fallback arm\");\n            };\n            Ok::<Datum, risingwave_expr::ExprError>(res)\n        } else {\n            Ok::<Datum, risingwave_expr::ExprError>(None)\n        }\n    }};\n}\n\nmacro_rules! lookup {\n    ($mode:ident, $this:expr, $datum:expr, $input:expr) => {{\n        match $datum.as_ref() {\n            Some(datum) => {\n                if let Some(expr) = $this.arms.get(datum) {\n                    let Ok(res) = risingwave_expr::forward!($mode, expr, eval_row($input)) else {\n                        bail!(\"failed to evaluate the input for normal arm\");\n                    };\n                    Ok(res)\n                } else {","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/impl/src/scalar/case.rs#L161-L197","documentation":"In the constant-lookup CASE implementation, when a lookup misses all arms the fallback (ELSE) expression is evaluated row-by-row. If that evaluation returns an Err, the macro cannot distinguish expression errors from control flow, so it rethrows this generic wrapper error, discarding the underlying cause.","triggerScenarios":"Evaluating a CASE expression built with `build_constant_lookup_expr` where the input datum matches no WHEN constant and the ELSE clause's evaluation fails on that row (e.g. cast overflow, division by zero, domain violation inside the else arm).","commonSituations":"ELSE clause performing arithmetic on NULL-typed or out-of-domain data; casts inside the else arm failing for particular rows in a materialized view refresh or query.","solutions":["Check the ELSE expression for operations that can fail per-row (casts, division, function domains) and make them total (COALESCE, safe casts).","Test the else expression standalone on the offending input values.","If you need the real root cause, run the same expression without the constant-lookup optimization path or check debug logs."],"exampleFix":"// before\nCASE key WHEN 1 THEN 'a' WHEN 2 THEN 'b' ELSE (val::int / divisor)::text END\n// after\nCASE key WHEN 1 THEN 'a' WHEN 2 THEN 'b' ELSE COALESCE((NULLIF(divisor,0) IS NULL, ...)::text, 'n/a') END","handlingStrategy":"try-catch","validationCode":"-- make the else arm total before execution\n-- ensure all casts in ELSE use COALESCE/NULLIF guards","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"failed to evaluate the input for fallback arm\") => {\n        // inspect ELSE expression inputs for the offending row\n    }\n    other => other?,\n}","preventionTips":["Keep ELSE expressions free of fallible casts and division.","Guard with COALESCE / NULLIF inside the else arm.","Test the CASE against edge-case rows before deploying the MV."],"tags":["rust","sql","case-expression","error-wrapping"],"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"}