risingwavelabs/risingwave · error
MATCH_RECOGNIZE WITHIN span predicate has type {}, expected
Error message
MATCH_RECOGNIZE WITHIN span predicate has type {}, expected boolean What it means
The `within` field must be a boolean span predicate evaluated per candidate row. The decoder found a non-boolean expression type and rejects the plan, since a non-boolean predicate cannot drive the span window logic.
Source
Thrown at src/stream/src/from_proto/match_recognize.rs:204
order_key_indices[0],
input.schema().len()
)
})?;
if let Some(deadline) = &within_deadline
&& deadline.return_type() != order_key_type
{
return Err(anyhow::anyhow!(
"MATCH_RECOGNIZE WITHIN deadline has type {} but the ORDER BY column has type {}; \
the two are compared directly",
deadline.return_type(),
order_key_type,
)
.into());
}
if let Some(predicate) = &within
&& predicate.return_type() != DataType::Boolean
{
return Err(anyhow::anyhow!(
"MATCH_RECOGNIZE WITHIN span predicate has type {}, expected boolean",
predicate.return_type(),
)
.into());
}
let vnode_bitmap = params.vnode_bitmap.clone().map(std::sync::Arc::new);
let state_table_catalog = node
.state_table
.as_ref()
.ok_or_else(|| anyhow::anyhow!("MATCH_RECOGNIZE node missing its state table"))?;
let state_table =
StateTableBuilder::new(state_table_catalog, store.clone(), vnode_bitmap.clone())
.forbid_preload_all_rows()
.build()
.await;
let exec = MatchRecognizeExecutor::new(MatchRecognizeExecutorArgs {
ctx: params.actor_context,View on GitHub (pinned to 6469eb736d)
Solutions
- Ensure the WITHIN expression is a boolean condition, e.g. `WITHIN (ts > now() - INTERVAL '1 hour')` rather than a bare column.
- Re-create the streaming job so the current binder regenerates the predicate.
- Align node versions to rule out version skew.
- If the SQL predicate is clearly boolean yet fails, report a binder bug.
Example fix
-- before MATCH_RECOGNIZE ( ORDER BY ts WITHIN ts ... ) -- after MATCH_RECOGNIZE ( ORDER BY ts WITHIN ts >= now() - INTERVAL '1 hour' ... )
Defensive patterns
Strategy: validation
Validate before calling
// SQL-level guard: WITHIN must be a boolean expression -- write WITHIN (<boolean condition>), e.g. WITHIN (ts >= now() - INTERVAL '1 hour')
Try / catch
// Pre-check decoded predicate type
if let Some(p) = &within && p.return_type() != DataType::Boolean {
return Err(anyhow!("WITHIN predicate must be boolean, got {}", p.return_type()));
} Prevention
- Always express WITHIN as a boolean condition, never a bare column or value.
- Check EXPLAIN output to confirm the predicate's inferred type is boolean.
- Add frontend tests covering non-boolean WITHIN inputs.
When it happens
Trigger: `new_boxed_executor` decodes a MatchRecognizeNode whose `within` expression's `return_type()` is not `DataType::Boolean` — e.g. the binder produced a raw column or arithmetic expression instead of a comparison.
Common situations: Writing `WITHIN <expr>` where `<expr>` is not a boolean condition (e.g. a column or numeric literal); frontend/binder bugs failing to wrap the expression in a comparison; version skew changing expression typing.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- MATCH_RECOGNIZE WITHIN deadline has type {} but the ORDER BY
- Filter can only receive bool array
- dynamic filter condition eval must return bool array
- Time column should be Timestamp or Timestamptz
- Chunk operation error: {0}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/92bcfbb39eee2f79.
Report an issue: GitHub.