risingwavelabs/risingwave · error
the streaming job shouldn't have an upstream fragment, job_t
Error message
the streaming job shouldn't have an upstream fragment, job_type: {:?} What it means
For streaming jobs of type Source or Table, the graph builder expects the job to have no upstream fragment in this replacement/edge-building path. If an upstream fragment is present for such a job type, the builder bails. This is a structural check that source- and table-type jobs never receive an upstream edge here.
Source
Thrown at src/meta/src/stream/stream_graph/fragment.rs:1885
downstream_fragment_id: id,
},
// We always use `NoShuffle` for the exchange between the upstream
// `Source` and the downstream `StreamScan` of the new MV.
dispatch_strategy: DispatchStrategy {
r#type: DispatcherType::NoShuffle as _,
dist_key_indices: vec![], // not used for `NoShuffle`
output_mapping: Some(output_mapping),
},
}
} else {
bail!(
"the upstream fragment should be a MView or Source, got fragment type: {:b}",
upstream_fragment.fragment_type_mask
)
}
}
StreamingJobType::Source | StreamingJobType::Table(_) => {
bail!(
"the streaming job shouldn't have an upstream fragment, job_type: {:?}",
job_type
)
}
};
// put the edge into the extra edges
extra_downstreams
.entry(upstream_root_fragment_id)
.or_insert_with(HashMap::new)
.try_insert(id, edge.clone())
.unwrap();
extra_upstreams
.entry(id)
.or_insert_with(HashMap::new)
.try_insert(upstream_root_fragment_id, edge)
.unwrap();
}View on GitHub (pinned to 6469eb736d)
Solutions
- Verify the streaming job's type metadata: a Source/Table job should not carry an upstream fragment here; fix the replacement plan generation.
- If this is a CREATE TABLE with a connector, ensure no upstream fragment id was mistakenly attached to the job.
- If triggered by normal DDL, capture the job type and fragment metadata and file a bug; try recreating the job as a workaround.
Example fix
null
Defensive patterns
Strategy: type-guard
Validate before calling
if matches!(job_type, StreamingJobType::Source | StreamingJobType::Table(_)) && upstream_fragment.is_some() {
return Err("Source/Table jobs must not have an upstream fragment here");
} Type guard
fn requires_no_upstream(job_type: &StreamingJobType) -> bool {
matches!(job_type, StreamingJobType::Source | StreamingJobType::Table(_))
} Prevention
- Never attach upstream fragment edges to Source/Table type jobs in replacement plans
- Validate replacement plans against job type before graph building
- Add tests covering Source and Table jobs in the replacement pipeline
When it happens
Trigger: Building a replacement graph for a `StreamingJobType::Source` or `StreamingJobType::Table(_)` job while the code path finds a non-empty upstream fragment for it, hitting the bail in the match arm.
Common situations: Schema-change/replacement plan construction where the job definition unexpectedly retains an upstream edge; bugs in replacement plan generation or hand-edited/incorrect job metadata.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- table_fragment does not exist: id={0}
- downstream relation missing for {} -> {}
- snapshot backfill epoch set again: {} {} {}
- the upstream fragment should be a MView or Source, got fragm
- graph is not a DAG
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/90ed47eb9a22a11f.
Report an issue: GitHub.