risingwavelabs/risingwave · error
range frame offset add expression must be sync
Error message
range frame offset add expression must be sync
What it means
When preparing a RangeFrameBounds, the generated add (and subtract) expression between the order column and offset is built via build_func; the result must be a synchronous (non-async/non-table) expression for the frame calculation to work inline. If build_func returns anything else, from_protobuf fails with this invariant error.
Solutions
- Use a supported order column type for RANGE frames (integer, numeric, date/timestamp, or compatible interval) so Add/Subtract build as sync expressions.
- Add a sync expression implementation for the missing type combination in the expression crate.
- Check recent expression-framework changes if this previously worked (BoxedExpression::Sync variant coverage).
Example fix
// ensure build_func result is sync for the type pair, or add an impl: // before: Add on timestamptz + interval-with-months falls to unsupported variant // after: restrict offset to microsecond-only intervals so Add maps to BoxedExpression::Sync
Defensive patterns
Strategy: try-catch
Try / catch
let add_expr = match build_func(PbExprType::Add, order_type.clone(), vec![input.boxed(), offset.boxed()]) {
Ok(crate::expr::BoxedExpression::Sync(e)) => e,
Ok(_) | Err(e2) => return Err(anyhow!("unsupported RANGE frame types (order/offset): {:?}", e2.map(|e| e.to_string()))),
}; Prevention
- Restrict RANGE frames to type pairs with sync Add/Subtract support.
- Add expression coverage tests for every supported order/offset type combination.
- Fail fast in the frontend binder when the order/offset types lack arithmetic support.
When it happens
Trigger: Deserializing a RANGE frame where PbExprType::Add (or Subtract) over the order/offset data types builds into a non-sync expression — typically an unsupported type combination that maps to an async or missing expression implementation.
Common situations: Exotic order-column/offset type pairs (e.g. certain decimal/interval/timestamptz combos) where the arithmetic expression engine has no sync implementation; expression framework refactors changing BoxedExpression variants.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- for frame bound offset of type `interval`, each field…
- for frame order column of type `timestamptz`, offset should…
- frame bound offset should be non-negative, but
- Array error
- async child in iceberg_transform is not supported
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/26f42e62664a57ae.
Report an issue: GitHub.
Appendix: source
Thrown at src/expr/core/src/window_function/range.rs:341
offset,
add_expr: None,
sub_expr: None,
}
}
fn prepare(&mut self, order_data_type: &DataType, offset_data_type: &DataType) -> Result<()> {
use risingwave_pb::expr::expr_node::PbType as PbExprType;
let input_expr = InputRefExpression::new(order_data_type.clone(), 0);
let offset_expr =
LiteralExpression::new(offset_data_type.clone(), Some(self.offset.clone()));
let add_expr = build_func(
PbExprType::Add,
order_data_type.clone(),
vec![input_expr.clone().boxed(), offset_expr.clone().boxed()],
)?;
let crate::expr::BoxedExpression::Sync(add_expr) = add_expr else {
bail!("range frame offset add expression must be sync");
};
self.add_expr = Some(add_expr);
let sub_expr = build_func(
PbExprType::Subtract,
order_data_type.clone(),
vec![input_expr.boxed(), offset_expr.boxed()],
)?;
let crate::expr::BoxedExpression::Sync(sub_expr) = sub_expr else {
bail!("range frame offset subtract expression must be sync");
};
self.sub_expr = Some(sub_expr);
Ok(())
}
pub fn new_for_test(
offset: ScalarImpl,
order_data_type: &DataType,View on GitHub (pinned to 6469eb736d)