risingwavelabs/risingwave · error · ExprError::Internal
expected RowNumberState, got {other:?}
Error message
expected RowNumberState, got {other:?} What it means
`RowNumber` window function state is deserialized from a protobuf `FunctionState`. If the received state variant is anything other than `FunctionState::RowNumberState`, the state does not match the function and deserialization fails with this internal error.
Source
Thrown at src/expr/impl/src/window_function/rank.rs:73
impl RankFuncCount for RowNumber {
fn count(&mut self, _curr_key: StateKey) -> i64 {
let curr_rank = self.prev_rank + 1;
self.prev_rank = curr_rank;
curr_rank
}
fn to_proto_state(&self) -> FunctionState {
FunctionState::RowNumberState(RowNumberState {
prev_rank: self.prev_rank,
})
}
fn from_proto_state(state: FunctionState) -> Result<Self> {
match state {
FunctionState::RowNumberState(s) => Ok(Self {
prev_rank: s.prev_rank,
}),
other => Err(ExprError::Internal(anyhow::anyhow!(
"expected RowNumberState, got {other:?}"
))),
}
}
}
#[derive(EstimateSize)]
pub(super) struct Rank {
prev_order_key: Option<MemcmpEncoded>,
prev_rank: i64,
// 1-based position of the previously output row within its peer group.
// Used to advance the rank by the peer-group size when a new group starts.
prev_pos_in_peer_group: i64,
}
impl Default for Rank {
fn default() -> Self {
Self {View on GitHub (pinned to 6469eb736d)
Solutions
- Full-rebuild / recreate the materialized view so state matches the current function kind
- Verify the state key maps to the correct function type in the streaming plan
- Check protobuf FunctionState encoding for version mismatch bugs
Example fix
// before
other => Err(ExprError::Internal(anyhow::anyhow!("expected RowNumberState, got {other:?}"))),
// after
FunctionState::RowNumberState(_) | FunctionState::RankState(_) => ... // handle variants explicitly, or add a default fallback Defensive patterns
Strategy: try-catch
Validate before calling
fn state_matches(state: &FunctionState) -> bool { matches!(state, FunctionState::RowNumberState(_)) } Type guard
fn as_row_number_state(s: &FunctionState) -> Option<&RowNumberState> { match s { FunctionState::RowNumberState(x) => Some(x), _ => None } } Try / catch
match RowNumber::from_proto_state(state) {
Err(e) if e.to_string().contains("expected RowNumberState") => rebuild_mv_state(),
other => other?,
} Prevention
- Never alter a window function kind without full-rebuilding the materialized view
- Version the persisted FunctionState and migrate on upgrade
- Use distinct state keys per function kind
When it happens
Trigger: `RowNumber::from_proto_state` receiving a FunctionState of a different variant (e.g. RankState or DenseRankState), typically from a mismatched state type written under the same state key during recovery or a bug in state serialization.
Common situations: Stream recovery after a schema/state version change; swapping a window function kind in a materialized view without full rebuild; corrupted or mismatched checkpoint state.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- expected RankState, got {other:?}
- expected DenseRankState, got {other:?}
- unspecified type of `WindowFrame`
- unspecified type of `FrameExclusion`
- Unspecified window function type
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/8e061c7879f53e9e.
Report an issue: GitHub.