risingwavelabs/risingwave · error
for session gap of type `interval`, each field should be…
Error message
for session gap of type `interval`, each field should be non-negative, but {} is given What it means
For interval-typed session gaps, a simple sign check is insufficient because an Interval has months/days/microseconds fields. Validation uses `is_never_negative()`, requiring every field of the interval to be non-negative (e.g. '1 month -1 day' is rejected even if the total duration is positive).
Solutions
- Rewrite the gap so all interval fields are non-negative (e.g. INTERVAL '1 month 1 day')
- Normalize the interval before passing it (split/abs each field)
- Clamp negative fields to zero in the expression producing the gap
Example fix
// before SESSION(INTERVAL '1 month -1 day') // after SESSION(INTERVAL '1 month 1 day')
Defensive patterns
Strategy: validation
Validate before calling
fn interval_never_negative(i: Interval) -> bool { i.is_never_negative() } Type guard
fn safe_interval_gap(i: Interval) -> bool { i.months() >= 0 && i.days() >= 0 && i.useconds() >= 0 } Try / catch
if !gap.is_never_negative() {
return Err(anyhow!("each interval field of the session gap must be non-negative"));
} Prevention
- Avoid interval arithmetic that mixes signs across fields
- Normalize/justify intervals before use as gaps
- Document per-field non-negativity for users
When it happens
Trigger: Session window with an interval gap where any component field is negative, e.g. `INTERVAL '1 month -1 day'` or `INTERVAL '-5 seconds'`, detected in `validate` (via `is_canonical`).
Common situations: Arithmetic on intervals producing mixed-sign components; users assuming total-duration semantics instead of per-field semantics.
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
- for session order column of type `timestamptz`, gap should…
- session frame gap add expression must be sync
- session gap should be non-negative, but
- {0}
- for frame bound offset of type `interval`, each field…
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/fbfd864e7063b535.
Report an issue: GitHub.
Appendix: source
Thrown at src/expr/core/src/window_function/session.rs:105
// TODO(rc): maybe can merge with `RangeFrameBounds::validate`
fn validate_non_negative(val: impl IsNegative + Display) -> Result<()> {
if val.is_negative() {
bail!("session gap should be non-negative, but {} is given", val);
}
Ok(())
}
match self.gap.as_scalar_ref_impl() {
ScalarRefImpl::Int16(val) => validate_non_negative(val)?,
ScalarRefImpl::Int32(val) => validate_non_negative(val)?,
ScalarRefImpl::Int64(val) => validate_non_negative(val)?,
ScalarRefImpl::Float32(val) => validate_non_negative(val)?,
ScalarRefImpl::Float64(val) => validate_non_negative(val)?,
ScalarRefImpl::Decimal(val) => validate_non_negative(val)?,
ScalarRefImpl::Interval(val) => {
if !val.is_never_negative() {
bail!(
"for session gap of type `interval`, each field should be non-negative, but {} is given",
val
);
}
if matches!(self.order_data_type, DataType::Timestamptz) {
// for `timestamptz`, we only support gap without `month` and `day` fields
if val.months() != 0 || val.days() != 0 {
bail!(
"for session order column of type `timestamptz`, gap should not have non-zero `month` and `day`",
);
}
}
}
_ => unreachable!(
"other order column data types are not supported and should be banned in frontend"
),
}
Ok(())View on GitHub (pinned to 6469eb736d)