risingwavelabs/risingwave · error
invalid MATCH_RECOGNIZE define slot kind: {}
Error message
invalid MATCH_RECOGNIZE define slot kind: {} What it means
A MATCH_RECOGNIZE DEFINE slot's protobuf `kind` decoded to UNSPECIFIED (unset or out-of-range wire value). The executor fails fast because every later match on the kind relies on it being concrete; silently defaulting would change the predicate's meaning.
Source
Thrown at src/stream/src/executor/match_recognize/executor.rs:377
)?;
let slots = pb
.slots
.iter()
.map(|s| {
let kind = s.kind();
// The binder rejects physical NEXT in DEFINE (a verdict depending on rows after
// the candidate needs per-candidate decidability), so no plan this frontend
// produces carries it — reject rather than evaluate a watermark-unsafe,
// arrival-order-dependent read from a skewed plan. UNSPECIFIED (also what an
// out-of-range wire value decodes to) fails fast rather than silently changing
// the predicate's meaning. Every later match on the kind relies on this.
if kind == DefineSlotKind::Next {
return Err(StreamExecutorError::from(anyhow::anyhow!(
"physical NEXT in a MATCH_RECOGNIZE DEFINE is not supported"
)));
}
if kind == DefineSlotKind::Unspecified {
return Err(StreamExecutorError::from(anyhow::anyhow!(
"invalid MATCH_RECOGNIZE define slot kind: {}",
s.kind
)));
}
Ok(DefineSlot {
kind,
vars: s.vars.clone(),
col_idx: s.col_idx as usize,
offset: s.offset as usize,
})
})
.collect::<StreamExecutorResult<Vec<_>>>()?;
Ok(CompiledDefine {
symbol: pb.symbol.clone(),
condition,
slots,
})
}View on GitHub (pinned to 6469eb736d)
Solutions
- Align frontend/backend versions so all DefineSlotKind values are understood.
- Re-create the streaming job to regenerate a valid plan.
- In tests, set a valid, supported kind on each define slot.
Example fix
// before
PbDefineSlot { kind: 42 } // out of range -> UNSPECIFIED
// after
PbDefineSlot { kind: DefineSlotKind::Expr as i32, .. } Defensive patterns
Strategy: validation
Validate before calling
// Ensure the kind is a known, supported value before deserialization:
let kind = s.kind();
if kind == DefineSlotKind::Unspecified {
return Err(anyhow!("unsupported define slot kind {}", s.kind));
} Try / catch
// Regenerate the plan when an unknown enum value is rejected:
match define_from_protobuf(&pb) {
Err(e) if e.to_string().contains("invalid MATCH_RECOGNIZE define slot kind") => regenerate_plan(),
r => r,
} Prevention
- Keep DefineSlotKind enums synchronized across frontend/backend versions.
- Use enum conversions, never raw integers, when setting kind fields.
- Round-trip test all DefineSlotKind variants.
When it happens
Trigger: DefineSlot::from_protobuf sees kind == DefineSlotKind::Unspecified, typically from an out-of-range i32 kind value or a kind field left unset.
Common situations: Version skew where a newer frontend emits a kind the backend doesn't know; corrupt plan; hand-written prost messages missing the kind.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- invalid MATCH_RECOGNIZE measure slot kind: {}
- MATCH_RECOGNIZE measure missing expression
- MATCH_RECOGNIZE SUM/AVG measure slot missing agg_call
- MATCH_RECOGNIZE define missing condition
- invalid MATCH_RECOGNIZE after_match_skip mode: {}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/7f5f17fa178c1dd3.
Report an issue: GitHub.