risingwavelabs/risingwave · error · MetaError

expected NoShuffle but got {:?}

Error message

expected NoShuffle but got {:?}

What it means

The same code path loads the dispatcher type of the source→source-backfill fragment relation and requires it to be DispatcherType::NoShuffle. Any other dispatcher type yields 'expected NoShuffle but got {:?}', because the source backfill rewrite is only valid for directly connected (no-shuffle) fragments.

Source

Thrown at src/meta/src/controller/fragment.rs:1755

        let fragment_relation: DispatcherType = FragmentRelation::find()
            .select_only()
            .column(fragment_relation::Column::DispatcherType)
            .filter(fragment_relation::Column::SourceFragmentId.eq(source_fragment_id))
            .filter(fragment_relation::Column::TargetFragmentId.eq(source_backfill_fragment_id))
            .into_tuple()
            .one(&txn)
            .await?
            .ok_or_else(|| {
                anyhow!(
                    "no fragment connection from source fragment {} to source backfill fragment {}",
                    source_fragment_id,
                    source_backfill_fragment_id
                )
            })?;

        if fragment_relation != DispatcherType::NoShuffle {
            return Err(anyhow!("expected NoShuffle but got {:?}", fragment_relation).into());
        }

        let load_fragment_distribution_type = |txn, fragment_id: FragmentId| async move {
            let result: MetaResult<DistributionType> = try {
                FragmentModel::find_by_id(fragment_id)
                    .select_only()
                    .column(fragment::Column::DistributionType)
                    .into_tuple()
                    .one(txn)
                    .await
                    .map_err(MetaError::from)?
                    .ok_or_else(|| {
                        MetaError::from(anyhow!("failed to find fragment: {}", fragment_id))
                    })?
            };
            result
        };

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Inspect the fragment_relation row's dispatcher type for the reported fragment pair
  2. Confirm the table was created by the currently deployed RisingWave version; recreate the table if it predates a schema change
  3. Do not manually edit the meta store; if it was edited, restore from backup
  4. File a RisingWave issue if stock metadata produces a non-NoShuffle edge here
Defensive patterns

Strategy: validation

Validate before calling

let dispatch = load_relation_dispatcher(txn, src, dst).await?;
if dispatch != DispatcherType::NoShuffle { return Err(skip_backfill()); }

Type guard

fn is_no_shuffle(d: &DispatcherType) -> bool { matches!(d, DispatcherType::NoShuffle) }

Try / catch

if let Err(e) = rewrite_for_source_backfill(...).await { if e.to_string().contains("expected NoShuffle") { /* metadata from unsupported layout */ } }

Prevention

When it happens

Trigger: Triggering a source backfill for a table whose source→backfill fragment relation row stores a dispatcher type other than NoShuffle — e.g. metadata written by a different plan generation or manually modified relation rows.

Common situations: Upgrades across versions where the default dispatch strategy changed; corrupted or hand-edited meta store; retrying a rewrite on a table whose fragment graph was produced by experimental/patched planner code.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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