risingwavelabs/risingwave · error
the window frame must be valid
Error message
the window frame must be valid
What it means
When constructing the window aggregate state, RisingWave validates the frame bounds with `bounds.validate()`. If the bounds are invalid (e.g. malformed UNBOUNDED/offset combinations), construction is aborted because the aggregate would produce undefined results while sliding the frame.
Solutions
- Fix the frontend/planner so only valid frames reach the executor
- Correct the OVER clause frame specification in the query
- Check `WindowFrameBounds::validate` logic if a legitimate frame is being rejected
Example fix
// before
bail!("the window frame must be valid");
// after
bail!("invalid window frame bounds: {:?}", call.frame.bounds); // at minimum log which bounds failed Defensive patterns
Strategy: validation
Validate before calling
fn frame_is_valid(bounds: &WindowFrameBounds) -> bool { bounds.validate().is_ok() } Try / catch
match result {
Err(e) if e.to_string().contains("window frame must be valid") => fix_or_reject_frame(query),
other => other?,
} Prevention
- Only emit frames from the frontend after calling bounds.validate()
- Add planner tests for offset FOLLOWING/PRECEDING combinations
- Reject invalid OVER clauses at SQL parse/plan time
When it happens
Trigger: Creating an aggregate window function (WindowFuncKind::Aggregate) whose WindowFrameBounds fail `validate()` — e.g. a frame with invalid start/end ordering or an offset frame that is not permitted.
Common situations: A planner/frontend bug letting a malformed OVER clause through; manual construction of WindowFuncCall in tests; a frame like ROWS BETWEEN 2 FOLLOWING AND 1 PRECEDING.
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
- aggregate function is not supported
- expect accumulate function
- expected DenseRankState, got
- expected RankState, got
- expected RowNumberState, got
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/afdf3e968e23efe5.
Report an issue: GitHub.
Appendix: source
Thrown at src/expr/impl/src/window_function/aggregate.rs:53
use super::buffer::{RangeWindow, RowsWindow, SessionWindow, WindowBuffer, WindowImpl};
type StateValue = SmallVec<[Datum; 2]>;
struct AggregateState<W>
where
W: WindowImpl<Key = StateKey, Value = StateValue>,
{
agg_impl: AggImpl,
arg_data_types: Vec<DataType>,
ignore_nulls: bool,
buffer: WindowBuffer<W>,
buffer_heap_size: KvSize,
}
pub(super) fn new(call: &WindowFuncCall) -> Result<BoxedWindowState> {
if call.frame.bounds.validate().is_err() {
bail!("the window frame must be valid");
}
let agg_type = must_match!(&call.kind, WindowFuncKind::Aggregate(agg_type) => agg_type);
let arg_data_types = call.args.arg_types().to_vec();
let agg_call = AggCall {
agg_type: agg_type.clone(),
args: call.args.clone(),
return_type: call.return_type.clone(),
column_orders: Vec::new(), // the input is already sorted
// TODO(rc): support filter on window function call
filter: None,
// TODO(rc): support distinct on window function call? PG doesn't support it either.
distinct: false,
direct_args: vec![],
};
let (agg_impl, enable_delta) = match agg_type {
AggType::Builtin(PbAggKind::FirstValue) => (AggImpl::Shortcut(Shortcut::FirstValue), false),
AggType::Builtin(PbAggKind::LastValue) => (AggImpl::Shortcut(Shortcut::LastValue), false),View on GitHub (pinned to 6469eb736d)