risingwavelabs/risingwave · error
intermediate state row has fewer columns ({}) than expected
Error message
intermediate state row has fewer columns ({}) than expected ({}) at call_index {}, state may be corrupted What it means
The over-window (EOWC) executor persists intermediate state as a row laid out as `[partition keys..., call results...]`. When restoring, `load_intermediate_state` validates that the deserialized row has exactly `num_partition_key_cols + num_calls` columns before dispatching values to each call's state. Fewer columns means the persisted row cannot match the current plan, so it throws this corruption error.
Source
Thrown at src/stream/src/executor/over_window/eowc.rs:276
for call_index in 0..num_calls {
let state_col = num_partition_key_cols + call_index;
if state_col < row.len() {
if let Some(state_bytes) = row.datum_at(state_col) {
let snapshot = decode_snapshot(state_bytes.into_bytea(), pk_serde)?;
debug!(
"Restoring intermediate state for partition {:?}, call_index {}, has_last_key: {}",
encoded_partition_key,
call_index,
snapshot.last_output_key.is_some()
);
partition
.states
.get_mut(call_index)
.unwrap()
.restore(snapshot)?;
}
} else {
return Err(anyhow::anyhow!(
"intermediate state row has fewer columns ({}) than expected ({}) \
at call_index {}, state may be corrupted",
row.len(),
num_partition_key_cols + num_calls,
call_index
)
.into());
}
}
partition.intermediate_state_row = Some(row);
}
Ok(())
}
/// Persist intermediate state snapshots to the state table.
fn persist_intermediate_state(
this: &mut ExecutorInner<S>,
partition: &mut Partition,View on GitHub (pinned to 6469eb736d)
Solutions
- Recreate the materialized view so intermediate state is rebuilt from source data
- Ensure the query definition is unchanged since the state was written; do not ALTER the query while relying on persisted over-window state
- Verify the backup/snapshot version matches the running RisingWave version before restoring
- If reproducible with a stable schema, file an issue with the error details (it reports actual vs expected column counts)
Defensive patterns
Strategy: try-catch
Validate before calling
// Before restore, verify the persisted state layout matches the current plan
let expected = num_partition_key_cols + num_calls;
if row.len() < expected {
return Err(format!("state row has {} cols, need {}", row.len(), expected));
} Type guard
fn state_row_shape_ok(row_len: usize, expected: usize) -> bool {
row_len >= expected
} Try / catch
match restore_result {
Err(e) if e.to_string().contains("intermediate state row has fewer columns") => {
// State/plan mismatch: rebuild the MV from source data
recreate_materialized_view();
}
other => other?,
} Prevention
- Do not modify the over-window query (partition keys or window calls) while relying on persisted state
- Keep backup and runtime RisingWave versions identical
- Run restore drills in staging to catch layout mismatches early
- Never manually alter internal state-table rows
When it happens
Trigger: Recovery reads an intermediate-state snapshot row whose column count is below `num_partition_key_cols + num_calls` — e.g. state written by a plan with fewer window function calls or partition keys, then restored under a changed query definition.
Common situations: Altering the query definition (adding window calls or partition keys) while reusing old persisted state; restoring from a backup of a different RisingWave version; corrupt/truncated state-table rows.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- corrupt MATCH_RECOGNIZE state row: seq column must be a non-
- next offset {:?} should be later than current offset {:?}
- new item epoch {} does not match current chunk offset epoch
- new item epoch {} does not exceed barrier offset epoch {}
- Division by zero
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/cdf0582cad2517b8.
Report an issue: GitHub.