risingwavelabs/risingwave · error · MetaError
fragment id {} from actor {} is different from fragment {}
Error message
fragment id {} from actor {} is different from fragment {} What it means
compose_fragment validates that every actor passed for a fragment actually declares the same fragment_id as the fragment being composed. If any actor's `fragment_id` disagrees with the enclosing `fragment_id`, the metadata would be internally inconsistent (an actor attached to the wrong fragment), so the controller bails out before persisting the fragment.
Source
Thrown at src/meta/src/controller/fragment.rs:427
let stream_node = stream_node.to_protobuf();
let mut upstream_fragments = HashSet::new();
visit_stream_node_body(&stream_node, |body| {
if let NodeBody::Merge(m) = body {
assert!(
upstream_fragments.insert(m.upstream_fragment_id),
"non-duplicate upstream fragment"
);
}
});
let mut pb_actors = vec![];
let mut pb_actor_status = HashMap::new();
let mut pb_actor_splits = HashMap::new();
for actor in actors {
if actor.fragment_id != fragment_id {
bail!(
"fragment id {} from actor {} is different from fragment {}",
actor.fragment_id,
actor.actor_id,
fragment_id
)
}
let ActorInfo {
actor_id,
fragment_id,
worker_id,
splits,
vnode_bitmap,
expr_context,
config_override,
..
} = actor;
View on GitHub (pinned to 6469eb736d)
Solutions
- Check where the actors vector was built and ensure each actor.fragment_id is set from the same fragment being composed
- Log the offending actor_id and fragment_id from the message to find which grouping step produced the mismatch
- If this follows an upgrade or manual meta-store edits, verify the streaming_job/actor rows in the meta DB are consistent
- Report a bug to RisingWave if the mismatch arises from stock plan creation, since callers are internal
Example fix
// before let actors = build_actors(&plan); // actors may span fragments // after let actors: Vec<_> = all_actors.into_iter().filter(|a| a.fragment_id == fragment_id).collect();
Defensive patterns
Strategy: validation
Validate before calling
assert!(actors.iter().all(|a| a.fragment_id == fragment_id), "actor/fragment id mismatch");
Type guard
fn all_actors_match_fragment(actors: &[Actor], fragment_id: FragmentId) -> bool { actors.iter().all(|a| a.fragment_id == fragment_id) } Prevention
- Derive each actor's fragment_id from the same loop that builds the fragment
- Filter actors by fragment_id before composing
- Add a debug assertion in actor-building code
When it happens
Trigger: Calling CatalogController::compose_fragment (internally during table fragment creation/persisting, e.g. create table MV/materialized view flow) with an actors list where at least one Actor has fragment_id != the fragment's id — typically a bug in code that groups actors into fragments.
Common situations: Custom stream plan generation or patched actor distribution code that assigns actors to fragments incorrectly; internal state corruption between the stream graph builder and the fragment composer; merging fragments from an older cluster upgraded across versions where actor metadata format changed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- cannot find StreamActor of actor {}
- fragment {} not found in shared actor info
- fragment {} missing in shared actor info map
- no fragment connection from source fragment {} to source bac
- expected NoShuffle but got {:?}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/f13e758b8331a05c.
Report an issue: GitHub.