risingwavelabs/risingwave · error
the upstream fragment should be a MView or Source, got fragm
Error message
the upstream fragment should be a MView or Source, got fragment type: {:b} What it means
When building the stream graph, downstream edges can only connect to an upstream fragment of type MView (materialized view) or Source without an explicit dispatcher being constructed. If the upstream fragment's type mask is anything else, the builder bails with this error. It prevents connecting a dispatcher-based edge to an upstream fragment that cannot serve as such an upstream.
Source
Thrown at src/meta/src/stream/stream_graph/fragment.rs:1878
"BUG: column not found in the upstream source node",
)?
};
StreamFragmentEdge {
id: EdgeId::UpstreamExternal {
upstream_job_id,
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())View on GitHub (pinned to 6469eb736d)
Solutions
- Check the SQL: ensure the upstream object is a materialized view or source; create an MV on top of the table if needed and build from that.
- Inspect `upstream_fragment.fragment_type_mask` and confirm the intended upstream; if the planner should have rewritten it, check the frontend plan for missing rewriting.
- Update RisingWave or file a bug with the DDL statement if a normal MV/Source upstream still triggers this.
Example fix
-- before: CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM base_table; (upstream is a Table materialize fragment) -- after: create an MV over it first CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM base_table; CREATE MATERIALIZED VIEW mv2 AS SELECT * FROM mv1;
Defensive patterns
Strategy: validation
Validate before calling
let ok = upstream_fragment.fragment_type_mask == (FragmentTypeMask::MView as u32)
|| upstream_fragment.fragment_type_mask == (FragmentTypeMask::Source as u32);
if !ok { return Err("upstream must be MView or Source"); } Type guard
fn is_mview_or_source(mask: u32) -> bool {
mask == FragmentTypeMask::MView as u32 || mask == FragmentTypeMask::Source as u32
} Try / catch
match build_stream_graph(job) {
Err(e) if e.to_string().contains("upstream fragment should be a MView or Source") => {
// fall back: create an MV over the upstream table first
}
other => other?,
} Prevention
- Build streaming jobs only from materialized views or sources
- Create an intermediate MV when the upstream is a table's materialize fragment
- Keep planner rewrites that convert table upstreams into MV chains intact
When it happens
Trigger: Creating a streaming job whose external upstream fragment has a fragment type other than MView or Source (e.g. a Table/ materialize fragment or any other mask) while the builder takes the NoShuffle-dispatcher path in graph building.
Common situations: Creating a table/sink whose upstream is another table's materialize fragment in a way the planner did not rewrite into a proper MV chain; version changes or planner bugs that leave an unexpected upstream fragment type.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- table_fragment does not exist: id={0}
- downstream relation missing for {} -> {}
- snapshot backfill epoch set again: {} {} {}
- the streaming job shouldn't have an upstream fragment, job_t
- graph is not a DAG
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/fdd1cf77192cd91c.
Report an issue: GitHub.