risingwavelabs/risingwave · error
failed to fold constant
Error message
failed to fold constant
What it means
Arguments to `internal_get_channel_delta_stats` must be constants so they can be evaluated at plan time. If constant folding of the argument expression itself returns an error, that error is wrapped with the context `failed to fold constant`.
Solutions
- Replace the argument with a plain constant literal.
- Remove volatile or non-deterministic functions from the argument expression.
- Fix the inner fold error shown by the anyhow cause chain (e.g. overflow or division by zero).
- Precompute the value client-side and inline it as a literal.
Example fix
-- before SELECT * FROM internal_get_channel_delta_stats(now()::bigint, 0); -- after SELECT * FROM internal_get_channel_delta_stats(1726000000, 0);
Defensive patterns
Strategy: validation
Validate before calling
-- Only pass literals, not expressions SELECT * FROM internal_get_channel_delta_stats(1726000000, 0);
Try / catch
match expr_impl_to_u64_fn(expr) {
Ok(v) => /* proceed */,
Err(e) => eprintln!("arg fold failed: {e:#}"), // inspect cause chain
} Prevention
- Use plain numeric literals for arguments
- Avoid volatile functions like now() in arguments
- Avoid arithmetic that can overflow/divide-by-zero at fold time
When it happens
Trigger: `build_plan` calls `expr_impl_to_u64_fn` on an argument whose fold produces `Some(Err(err))` — e.g. the expression contains a volatile function, division by zero during folding, or a fold-time type error.
Common situations: Passing expressions that reference columns or volatile functions (`now()`), or arithmetic that fails during evaluation (overflow, division by zero).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- expression must be a constant value
- call predicate_pushdown of the PlanRef instead of calling…
- call prune_col of the PlanRef instead of calling directly…
- ` ` column not found in backfill table
- expected int64, got
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/736af2a5aac30837.
Report an issue: GitHub.
Appendix: source
Thrown at src/frontend/src/optimizer/rule/table_function_to_internal_get_channel_delta_stats.rs:55
Some(Ok(value)) => {
let Some(scalar) = value else {
return Ok(None);
};
match scalar {
ScalarImpl::Int64(value) => {
if value < 0 {
Err(anyhow::anyhow!(
"time parameter cannot be negative, got {}",
value
))
} else {
Ok(Some(value as u64))
}
}
_ => Err(anyhow::anyhow!("expected int64, got {:?}", scalar)),
}
}
Some(Err(err)) => Err(anyhow!(err).context("failed to fold constant")),
None => Err(anyhow::anyhow!("expression must be a constant value")),
}
}
/// Transform the `internal_get_channel_delta_stats()` table function
/// into a plan graph which will return channel statistics from the dashboard API.
/// It will return channel stats with `upstream_fragment_id` and `downstream_fragment_id` as primary key.
pub struct TableFunctionToInternalGetChannelDeltaStatsRule {}
impl FallibleRule<Logical> for TableFunctionToInternalGetChannelDeltaStatsRule {
fn apply(&self, plan: PlanRef) -> ApplyResult<PlanRef> {
let logical_table_function: &LogicalTableFunction = plan.as_logical_table_function()?;
if logical_table_function.table_function().function_type
!= TableFunctionType::InternalGetChannelDeltaStats
{
return ApplyResult::NotApplicable;
}
let plan = Self::build_plan(plan.ctx(), logical_table_function.table_function())?;
ApplyResult::Ok(plan)View on GitHub (pinned to 6469eb736d)