{"record":{"id":"8bf86afe92619c88","repo":"risingwavelabs/risingwave","slug":"since-timestamp-epoch-has-not-been-resolved-for-sn","errorCode":null,"errorMessage":"since_timestamp epoch has not been resolved for snapshot backfill","messagePattern":"since_timestamp epoch has not been resolved for snapshot backfill","errorType":"validation","errorClass":"MetaError","httpStatus":null,"severity":"error","filePath":"src/meta/src/barrier/checkpoint/state.rs","lineNumber":547,"sourceCode":"                    &self.database_info,\n                    &info.definition,\n                    &info.stream_job_fragments.inner.ctx,\n                    &info.streaming_job_model,\n                    partial_graph_manager\n                        .control_stream_manager()\n                        .env\n                        .actor_id_generator(),\n                    worker_nodes,\n                    &ensembles,\n                    &info.database_resource_group,\n                )?;\n                {\n                    assert!(!self.state.is_paused());\n                    let (snapshot_epoch, since_timestamp_upstream_log_epochs) =\n                        if let Some(since_epoch) = &since_epoch {\n                            let (snapshot_epoch, log_epochs) =\n                                since_epoch.resolved.as_ref().ok_or_else(|| {\n                            MetaError::from(anyhow::anyhow!(\n                                \"since_timestamp epoch has not been resolved for snapshot backfill\"\n                            ))\n                        })?;\n                            (\n                                *snapshot_epoch,\n                                Some((\n                                    log_epochs,\n                                    to_partial_graph_id(self.database_id, None),\n                                    barrier_info.prev_epoch(),\n                                )),\n                            )\n                        } else {\n                            (barrier_info.prev_epoch(), None)\n                        };\n                    // set snapshot epoch of upstream table for snapshot backfill\n                    for snapshot_backfill_epoch in snapshot_backfill_info\n                        .upstream_mv_table_id_to_backfill_epoch\n                        .values_mut()","sourceCodeStart":529,"sourceCodeEnd":565,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/barrier/checkpoint/state.rs#L529-L565","documentation":"During a snapshot-backfill streaming job creation, the caller supplied a since_timestamp epoch whose resolution is still pending (ResolvedEpoch::resolved is None). The barrier command applier requires the concrete snapshot epoch before it can apply the CreateStreamingJob command, so it refuses to proceed. This is an ordering/state invariant: the epoch must be resolved by barrier scheduling before the command is applied.","triggerScenarios":"Applying a CreateStreamingJob command with CreateStreamingJobType::SnapshotBackfill (or batch refresh with since epoch) via handle_new_barrier while since_epoch.resolved is still None — i.e. the resolution step did not run or ran after apply.","commonSituations":"Race between barrier resolution and command application; snapshot backfill created on a database whose barrier scheduler has not yet resolved the since_timestamp; internal scheduling bugs after upgrades touching barrier state.","solutions":["Ensure the since_timestamp epoch is resolved (resolve_since_timestamp_log_store_epoch) before the command reaches apply_command","Retry creating the snapshot backfill job after the next barrier completes","Check barrier scheduler ordering/feature flag for since_timestamp resolution","Report as a bug if it reproduces consistently — resolution should precede application"],"exampleFix":"// before: apply immediately with unresolved since epoch\ncommand.apply()\n// after: wait for resolution\nif since_epoch.resolved.is_none() { defer_to_next_barrier(command); }","handlingStrategy":"validation","validationCode":"if since_epoch.resolved.is_none() {\n    return Err(\"defer command until since_timestamp is resolved\");\n}\ncommand.apply();","typeGuard":"fn is_resolved(e: &SinceEpoch) -> bool { e.resolved.is_some() }","tryCatchPattern":"match apply_command(&mut state, cmd) {\n    Err(e) if e.to_string().contains(\"not been resolved\") => defer_to_next_barrier(cmd),\n    other => other,\n}","preventionTips":["Only enqueue snapshot-backfill commands after since-epoch resolution","Track resolution status in job metadata before applying","Add assertions/tests covering unresolved since-epoch paths"],"tags":["meta","barrier","snapshot-backfill","rust"],"backgroundTag":"invalid-state-transition","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"}