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
- Inspect the fragment_relation row's dispatcher type for the reported fragment pair
- Confirm the table was created by the currently deployed RisingWave version; recreate the table if it predates a schema change
- Do not manually edit the meta store; if it was edited, restore from backup
- 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
- Avoid manual edits to fragment_relation dispatcher values
- Recreate tables created under incompatible planner versions
- Assert NoShuffle edges in meta consistency tests
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
- no fragment connection from source fragment {} to source bac
- fragment id {} from actor {} is different from fragment {}
- failed to find fragment: {}
- sink fragment not found for sink id {}
- fragments {:?} not found
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/31f941bb3ac3f174.
Report an issue: GitHub.