{"record":{"id":"7e24dc576ce55f5d","repo":"risingwavelabs/risingwave","slug":"invalid-persisted-stream-scan-type-in-job-fr","errorCode":null,"errorMessage":"invalid persisted stream scan type {} in job {} fragment {}","messagePattern":"invalid persisted stream scan type (.+?) in job (.+?) fragment (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/controller/streaming_job.rs","lineNumber":311,"sourceCode":"            })\n            .collect();\n        if !job_info.is_empty() {\n            let fragments = Fragment::find()\n                .filter(fragment::Column::JobId.is_in(job_info.keys().copied()))\n                .all(&inner.db)\n                .await?;\n            for fragment in fragments {\n                let info = job_info\n                    .get_mut(&fragment.job_id)\n                    .expect(\"job should exist\");\n                info.state_table_ids\n                    .extend(fragment.state_table_ids.inner_ref().iter().copied());\n                let mut collection_error = None;\n                visit_stream_node_stream_scan(&fragment.stream_node.to_protobuf(), |stream_scan| {\n                    let scan_type = match StreamScanType::try_from(stream_scan.stream_scan_type) {\n                        Ok(scan_type) => scan_type,\n                        Err(err) => {\n                            collection_error = Some(anyhow::Error::new(err).context(format!(\n                                \"invalid persisted stream scan type {} in job {} fragment {}\",\n                                stream_scan.stream_scan_type, fragment.job_id, fragment.fragment_id\n                            )));\n                            return;\n                        }\n                    };\n                    if scan_type != StreamScanType::SnapshotBackfill {\n                        return;\n                    }\n                    match info\n                        .upstream_table_snapshot_epochs\n                        .entry(stream_scan.table_id)\n                    {\n                        std::collections::hash_map::Entry::Occupied(entry) => {\n                            if entry.get() != &stream_scan.snapshot_backfill_epoch {\n                                collection_error = Some(anyhow!(\n                                    \"job {} has inconsistent snapshot epochs for upstream table {}\",\n                                    fragment.job_id,","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/controller/streaming_job.rs#L293-L329","documentation":"The meta service persisted a stream scan node in a fragment whose stream_scan_type value does not map to any known StreamScanType enum variant in the protobuf definition. This indicates a corrupt or forward-incompatible persisted catalog: the stored proto value is not a valid enum discriminant. It is raised while collecting change-log truncate info for a job's state tables.","triggerScenarios":"Calling get_table_change_log_truncate_info when a fragment's persisted StreamNode contains a stream_scan_type value not defined in the current StreamScanType proto enum (e.g. meta built from older/newer code reading a catalog written by a different version).","commonSituations":"Version skew between meta node and persisted metadata (upgrade/rollback), corrupted cluster state after failed migration, or manually edited catalog storage.","solutions":["Check RisingWave version consistency; do not mix meta binary versions against one cluster state.","Rebuild or drop the affected streaming job (job_id from the message) and recreate it.","If this appeared after an upgrade/rollback, restore metadata from backup taken at a compatible version.","Inspect the persisted fragment proto in the metadata store to confirm the invalid discriminant."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before depending on persisted scan info\nif StreamScanType::try_from(stream_scan.stream_scan_type).is_err() {\n    // skip this job / surface unsupported-value instead of proceeding\n}","typeGuard":null,"tryCatchPattern":"match get_table_change_log_truncate_info().await {\n    Err(e) if e.to_string().contains(\"invalid persisted stream scan type\") => /* version skew: pin meta binary version or recreate job */,\n    other => other?,\n}","preventionTips":["Keep all meta nodes on the same RisingWave version","Never roll back upgrades past metadata migrations","Back up the meta store before upgrades"],"tags":["meta","catalog","protobuf","enum"],"backgroundTag":"invalid-enum-value","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}