risingwavelabs/risingwave · error
time parameter cannot be negative, got
Error message
time parameter cannot be negative, got {} What it means
`expr_impl_to_u64_fn` converts a constant expression argument of `internal_get_channel_delta_stats` to u64. Int64 arguments are rejected if negative because a time parameter (at_time / time offset) cannot be negative.
Solutions
- Pass non-negative int64 values for both time arguments.
- If a relative offset, use the absolute difference or clamp negatives to 0.
- Wrap the argument expression so constant folding yields a non-negative value.
- Check unit semantics (seconds vs millis) which may have led to the negative value.
Example fix
-- before SELECT * FROM internal_get_channel_delta_stats(-60, 0); -- after SELECT * FROM internal_get_channel_delta_stats(60, 0);
Defensive patterns
Strategy: validation
Validate before calling
-- Guard in SQL before calling -- Ensure args are >= 0: use GREATEST(0, x) or check in client code
Type guard
fn as_non_neg_i64(v: i64) -> Option<u64> {
if v < 0 { None } else { Some(v as u64) }
} Try / catch
match expr_impl_to_u64_fn(expr) {
Ok(v) => /* use v */,
Err(e) => eprintln!("time parameter rejected: {e:#}"),
} Prevention
- Clamp computed offsets with GREATEST(0, ...)
- Validate offsets client-side before issuing queries
- Double-check unit conversions that can produce negatives
When it happens
Trigger: `build_plan` for `internal_get_channel_delta_stats(at_time, time_offset)` folds an argument to a constant Int64 whose value is < 0, e.g. `internal_get_channel_delta_stats(-100, 200)`.
Common situations: Passing negative relative offsets by mistake, or computing offsets with expressions that evaluate to negative values (clock skew calculations).
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- internal_get_channel_delta_stats expects 0 or 2 arguments
- bounded compaction head sequence
- 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
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/286ea1193bdceb61.
Report an issue: GitHub.
Appendix: source
Thrown at src/frontend/src/optimizer/rule/table_function_to_internal_get_channel_delta_stats.rs:44
/// Helper function to extract a constant u64 value from an `ExprImpl`.
/// Returns `Ok(Some(value))` if the expression can be folded to a constant u64,
/// `Ok(None)` if the expression is null, or an error if folding fails.
/// Negative values are rejected as they are not valid for time parameters.
fn expr_impl_to_u64_fn(arg: &crate::expr::ExprImpl) -> anyhow::Result<Option<u64>> {
match arg
.clone()
.cast_implicit(&DataType::Int64)?
.try_fold_const()
{
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.View on GitHub (pinned to 6469eb736d)