{"record":{"id":"cdf0582cad2517b8","repo":"risingwavelabs/risingwave","slug":"intermediate-state-row-has-fewer-columns-than","errorCode":null,"errorMessage":"intermediate state row has fewer columns ({}) than expected ({}) at call_index {}, state may be corrupted","messagePattern":"intermediate state row has fewer columns \\((.+?)\\) than expected \\((.+?)\\) at call_index (.+?), state may be corrupted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/over_window/eowc.rs","lineNumber":276,"sourceCode":"            for call_index in 0..num_calls {\n                let state_col = num_partition_key_cols + call_index;\n                if state_col < row.len() {\n                    if let Some(state_bytes) = row.datum_at(state_col) {\n                        let snapshot = decode_snapshot(state_bytes.into_bytea(), pk_serde)?;\n                        debug!(\n                            \"Restoring intermediate state for partition {:?}, call_index {}, has_last_key: {}\",\n                            encoded_partition_key,\n                            call_index,\n                            snapshot.last_output_key.is_some()\n                        );\n                        partition\n                            .states\n                            .get_mut(call_index)\n                            .unwrap()\n                            .restore(snapshot)?;\n                    }\n                } else {\n                    return Err(anyhow::anyhow!(\n                        \"intermediate state row has fewer columns ({}) than expected ({}) \\\n                        at call_index {}, state may be corrupted\",\n                        row.len(),\n                        num_partition_key_cols + num_calls,\n                        call_index\n                    )\n                    .into());\n                }\n            }\n            partition.intermediate_state_row = Some(row);\n        }\n        Ok(())\n    }\n\n    /// Persist intermediate state snapshots to the state table.\n    fn persist_intermediate_state(\n        this: &mut ExecutorInner<S>,\n        partition: &mut Partition,","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/over_window/eowc.rs#L258-L294","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Before restore, verify the persisted state layout matches the current plan\nlet expected = num_partition_key_cols + num_calls;\nif row.len() < expected {\n    return Err(format!(\"state row has {} cols, need {}\", row.len(), expected));\n}","typeGuard":"fn state_row_shape_ok(row_len: usize, expected: usize) -> bool {\n    row_len >= expected\n}","tryCatchPattern":"match restore_result {\n    Err(e) if e.to_string().contains(\"intermediate state row has fewer columns\") => {\n        // State/plan mismatch: rebuild the MV from source data\n        recreate_materialized_view();\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["rust","streaming","state-corruption","over-window"],"backgroundTag":"schema-validation-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}