{"record":{"id":"b2291b497800390d","repo":"risingwavelabs/risingwave","slug":"snapshot-backfill-job-has-not-set-snapshot-epoc","errorCode":null,"errorMessage":"snapshot backfill job {} has not set snapshot epoch","messagePattern":"snapshot backfill job (.+?) has not set snapshot epoch","errorType":"error_code","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/meta/src/barrier/rpc.rs","lineNumber":846,"sourceCode":"                )\n            })?;\n            let mut snapshot_epoch = None;\n            let upstream_table_ids: HashSet<_> = snapshot_backfill_info\n                .upstream_mv_table_id_to_backfill_epoch\n                .keys()\n                .cloned()\n                .collect();\n            for (upstream_table_id, epoch) in\n                snapshot_backfill_info.upstream_mv_table_id_to_backfill_epoch\n            {\n                let epoch = epoch.ok_or_else(|| anyhow!(\"recovered snapshot backfill job {} to upstream {} has not set snapshot epoch\", job_id, upstream_table_id))?;\n                let snapshot_epoch = snapshot_epoch.get_or_insert(epoch);\n                if *snapshot_epoch != epoch {\n                    return Err(anyhow!(\"snapshot epoch {} to upstream {} different to snapshot epoch {} to previous upstream\", epoch, upstream_table_id, snapshot_epoch).into());\n                }\n            }\n            let snapshot_epoch = snapshot_epoch.ok_or_else(|| {\n                anyhow!(\n                    \"snapshot backfill job {} has not set snapshot epoch\",\n                    job_id\n                )\n            })?;\n            for upstream_table_id in &upstream_table_ids {\n                subscribers\n                    .entry(*upstream_table_id)\n                    .or_default()\n                    .try_insert(job_id.as_subscriber_id(), SubscriberType::SnapshotBackfill)\n                    .expect(\"non-duplicate\");\n            }\n            ongoing_snapshot_backfill_jobs\n                .try_insert(\n                    job_id,\n                    (\n                        fragment_infos,\n                        upstream_table_ids,\n                        committed_epoch,","sourceCodeStart":828,"sourceCodeEnd":864,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/barrier/rpc.rs#L828-L864","documentation":"After validating all per-upstream epochs, recovery consolidates a single snapshot epoch with `snapshot_epoch.get_or_insert(epoch)` inside the loop; if the loop body never ran (the map was empty), the Option is still None and `ok_or_else` throws this error. A snapshot backfill job with no upstream epochs recorded cannot determine its snapshot point, so recovery aborts.","triggerScenarios":"Recovering a snapshot backfill job whose `upstream_mv_table_id_to_backfill_epoch` map is empty, leaving `snapshot_epoch` unset.","commonSituations":"Job persisted before any upstream was registered; metadata corruption or truncation; upstream list cleared by a faulty recovery path.","solutions":["Verify the job's upstream mapping in the meta store; it must be non-empty.","Recreate the snapshot backfill job if its persisted state is empty.","Restore meta from a backup taken when the job was fully initialized.","Report a bug if the job had upstreams before the crash/recovery."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure the upstream map is non-empty before recovery\nif snapshot_backfill_info\n    .upstream_mv_table_id_to_backfill_epoch\n    .is_empty()\n{\n    // recreate job or fail fast with a clear message\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Refuse to persist a snapshot backfill job with zero upstream entries.","Verify job completeness after crash recovery.","Test recovery against jobs persisted at every initialization stage."],"tags":["meta","recovery","backfill","epoch"],"backgroundTag":"empty-required-field","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"}