risingwavelabs/risingwave · error

fragment not found in previous state

Error message

fragment {} not found in previous state

What it means

While assembling per-fragment actor sets, `build_reschedule_commands` looks up each fragment in `all_prev_fragments` to obtain its current actor ids. A fragment referenced by the plan but missing from the previous-state snapshot is an unrecoverable inconsistency, so it returns this error. It guarantees the reschedule diff operates on fragments the job actually has.

Solutions

  1. Retry the reschedule once concurrent DDL on the job has settled so the snapshot matches current state.
  2. Rebuild the context, ensuring `all_prev_fragments` is refreshed atomically with the diff inputs.
  3. Check the logged fragment_id against the job's fragments to find where the stale reference originates.
  4. Serialize DDL and reschedule operations on the same job to avoid snapshot/version skew.
Defensive patterns

Strategy: retry

Try / catch

match build_reschedule_from_context(ctx).await {
    Err(e) if e.to_string().contains("not found in previous state") => {
        // snapshot drift: rebuild and retry once
        let fresh_ctx = rebuild_context().await?;
        build_reschedule_from_context(fresh_ctx).await
    }
    r => r,
}

Prevention

When it happens

Trigger: Calling `build_reschedule_from_context` where a fragment id being diffed (from the reschedule diff or rendered output) has no entry in `all_prev_fragments` — e.g. a fragment created/deleted by a concurrent schema change between snapshot collection and diff computation.

Common situations: Race between `ALTER TABLE`/refresh and a reschedule on the same job; passing a context built for a different job version; catalog state changed since the context snapshot was captured.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at src/meta/src/stream/scale.rs:872

            let downstream_fragments = all_downstream_fragments
                .remove(&(*fragment_id as FragmentId))
                .unwrap_or_default();

            let fragment_actors: HashMap<_, _> = upstream_fragments
                .keys()
                .copied()
                .chain(downstream_fragments.keys().copied())
                .map(|fragment_id| {
                    all_prev_fragments
                        .get(&fragment_id)
                        .map(|fragment| {
                            (
                                fragment_id,
                                fragment.actors.keys().copied().collect::<HashSet<_>>(),
                            )
                        })
                        .ok_or_else(|| {
                            MetaError::from(anyhow!(
                                "fragment {} not found in previous state",
                                fragment_id
                            ))
                        })
                })
                .collect::<MetaResult<_>>()?;

            all_fragment_actors.extend(fragment_actors);

            let source_fragment_actors = actors
                .iter()
                .map(|(actor_id, info)| (*actor_id, info.vnode_bitmap.clone()))
                .collect();

            let mut all_actor_dispatchers: HashMap<_, Vec<_>> = HashMap::new();

            for downstream_fragment_id in downstream_fragments.keys() {
                let target_fragment_actors =

View on GitHub (pinned to 6469eb736d)