risingwavelabs/risingwave · error · ExprError
{0}
Error message
{0} What it means
ExprError::Custom is a pass-through variant that surfaces an arbitrary error message verbatim, primarily used to propagate UDF (user-defined function) errors into the expression error type. The message content comes entirely from the caller, most often external UDF code. Nothing is added by the framework, so diagnosis depends on the UDF author's message.
Source
Thrown at src/expr/core/src/error.rs:124
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.
#[error("error while evaluating expression `{display}`")]
Function {
display: Box<str>,
#[backtrace]
// We don't use `anyhow::Error` because we don't want to always capture the backtrace.
source: Box<dyn std::error::Error + Send + Sync>,
},
}
static_assertions::const_assert_eq!(std::mem::size_of::<ExprError>(), 40);
impl ExprError {
/// Constructs a [`ExprError::Function`] error with the given information for display.View on GitHub (pinned to 6469eb736d)
Solutions
- Read the raw message — it originates from the UDF itself
- Fix the input data or arguments that caused the UDF to fail
- Check the UDF implementation/service logs for the underlying cause
- If the UDF is external, verify the UDF service is running and reachable
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate UDF inputs before calling
if !udf_inputs_valid(args) { return Err("invalid UDF args"); } Try / catch
match result { Err(ExprError::Custom(msg)) => { log::error!("UDF failed: {msg}"); fallback_or_abort(msg) }, Ok(v) => v, Err(e) => return Err(e) } Prevention
- Test UDFs against edge-case and null inputs before deploying
- Monitor UDF service health if using external UDFs
- Wrap UDF logic with its own input validation
When it happens
Trigger: A UDF returns an error (e.g. via a failed external function call), and the UDF runtime wraps that error message into ExprError::Custom.
Common situations: Python/JavaScript/SQL UDFs raising exceptions or returning error strings; remote UDF services returning failure payloads; misconfigured UDF external servers.
Related errors
- UDF returned a value of type {} while the declared return ty
- UDF aggregate {what} has {} rows, but expected exactly 1
- UDF returned {} rows, but expected {}
- UDF returned no columns
- UDF returned {:?}, but expected {:?}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/cd2f5923a060d273.
Report an issue: GitHub.