risingwavelabs/risingwave · error

must be either all snapshot_backfill or no…

Error message

must be either all snapshot_backfill or no snapshot_backfill. Curr: {stream_scan:?} Prev: {prev_stream_scan:?}

What it means

`collect_snapshot_backfill_info_impl` walks all StreamScan nodes across fragments and requires them to be uniformly either all snapshot-backfill scans or all non-snapshot-backfill scans. A mix (one scan has snapshot backfill info, another doesn't, or vice versa) makes epoch filling ambiguous, so it errors, naming the current and previous conflicting scans.

Solutions

  1. Make all MV scans in the job consistent: either all snapshot backfill or none (recreate the offending MV).
  2. Check each upstream MV's stream_scan_type and align creation settings (snapshot backfill config) across the chain.
  3. If a version upgrade changed scan types, recreate dependent MVs so the graph is uniform.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure all upstream MV scans in the chain use a uniform snapshot-backfill setting
// before creating dependent MVs.

Prevention

When it happens

Trigger: Building/refreshing a graph where some fragments contain StreamScan nodes of type SnapshotBackfill and others contain plain StreamScan nodes over MVs — e.g. a job mixing snapshot-backfill MV scans with regular MV scans.

Common situations: Creating MVs that chain over other MVs where only some upstreams were created with snapshot backfill enabled; inconsistent stream_scan_type after plan changes or version upgrades.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/6f5a3c53289022e7. Report an issue: GitHub.

Appendix: source

Thrown at src/meta/src/stream/stream_graph/fragment.rs:1271

                        }
                        _ => false,
                    };

                    match &mut prev_stream_scan {
                        Some((prev_snapshot_backfill_info, prev_stream_scan)) => {
                            match (prev_snapshot_backfill_info, is_snapshot_backfill) {
                                (Some(prev_snapshot_backfill_info), true) => {
                                    prev_snapshot_backfill_info
                                        .upstream_mv_table_id_to_backfill_epoch
                                        .insert(
                                            stream_scan.table_id,
                                            stream_scan.snapshot_backfill_epoch,
                                        );
                                    true
                                }
                                (None, false) => true,
                                (_, _) => {
                                    result = Err(anyhow!("must be either all snapshot_backfill or no snapshot_backfill. Curr: {stream_scan:?} Prev: {prev_stream_scan:?}").into());
                                    false
                                }
                            }
                        }
                        None => {
                            prev_stream_scan = Some((
                                if is_snapshot_backfill {
                                    Some(SnapshotBackfillInfo {
                                        upstream_mv_table_id_to_backfill_epoch: HashMap::from_iter(
                                            [(
                                                stream_scan.table_id,
                                                stream_scan.snapshot_backfill_epoch,
                                            )],
                                        ),
                                    })
                                } else {
                                    None
                                },

View on GitHub (pinned to 6469eb736d)