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.

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)

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.