risingwavelabs/risingwave · error
Project node must have exactly 1 input for auto schema chang
Error message
Project node must have exactly 1 input for auto schema change, but got {:?} What it means
When the sink fragment's node under the sink is a Project (used for auto schema change), the code expects that Project to have exactly one input (the StreamScan). If the Project node has any other number of inputs, this error is returned. The message misleadingly formats `stream_input_node.input.len()` with `{:?}`.
Source
Thrown at src/meta/src/stream/stream_graph/fragment.rs:419
return Err(anyhow!(
"sink with auto schema change should have only 1 fragment, but got {:?}",
fragments.len()
)
.into());
}
let (_, fragment) = fragments.first_key_value().expect("non-empty");
let sink_node = &fragment.nodes;
let PbNodeBody::Sink(_) = sink_node.node_body.as_ref().unwrap() else {
return Err(anyhow!("expect PbNodeBody::Sink but got: {:?}", sink_node.node_body).into());
};
let [stream_input_node] = sink_node.input.as_slice() else {
panic!("Sink has more than 1 input: {:?}", sink_node.input);
};
let stream_scan_node = match stream_input_node.node_body.as_ref().unwrap() {
PbNodeBody::StreamScan(_) => stream_input_node,
PbNodeBody::Project(_) => {
let [stream_scan_node] = stream_input_node.input.as_slice() else {
return Err(anyhow!(
"Project node must have exactly 1 input for auto schema change, but got {:?}",
stream_input_node.input.len()
)
.into());
};
stream_scan_node
}
_ => {
return Err(anyhow!(
"expect PbNodeBody::StreamScan or PbNodeBody::Project but got: {:?}",
stream_input_node.node_body
)
.into());
}
};
let PbNodeBody::StreamScan(scan) = stream_scan_node.node_body.as_ref().unwrap() else {
return Err(anyhow!(
"expect PbNodeBody::StreamScan but got: {:?}",View on GitHub (pinned to 6469eb736d)
Solutions
- Confirm the sink was created with schema refresh supported (single-arrangement-backfill source); recreate the sink if its graph was built by an older planner.
- Check frontend and meta versions match; redeploy with aligned binaries.
- Inspect the fragment graph in meta logs to see the actual input count of the project node.
- Report to RisingWave if a supported `CREATE SINK` triggers it.
Example fix
// before
let [stream_scan_node] = stream_input_node.input.as_slice() else { ... };
// after: handle the shape explicitly upstream
if stream_input_node.input.len() != 1 {
return Err(anyhow!("unexpected project fan-in {} for schema refresh", stream_input_node.input.len()).into());
}
let [stream_scan_node] = stream_input_node.input.as_slice() else { unreachable!() }; Defensive patterns
Strategy: validation
Validate before calling
if let Some(PbNodeBody::Project(_)) = stream_input_node.node_body.as_ref() {
assert_eq!(stream_input_node.input.len(), 1, "project fan-in must be 1");
} Type guard
fn is_single_input_project(node: &StreamNode) -> Option<&StreamNode> {
match (node.node_body.as_ref(), node.input.as_slice()) {
(Some(PbNodeBody::Project(_)), [only]) => Some(only),
_ => None,
}
} Prevention
- Only rely on auto schema refresh for the canonical sink-over-backfill topology.
- Diff fragment graphs after planner upgrades in staging.
- Avoid hand-editing or migrating fragment metadata across versions.
When it happens
Trigger: `generate_streaming_job` -> `check_sink_fragments_support_refresh_schema` encountering a `PbNodeBody::Project` node between the sink and the stream scan whose `input` slice is not exactly length 1 (0 or 2+ inputs).
Common situations: Auto schema change (schema registry evolution, e.g. adding/removing columns on a table being backfilled into a sink) producing an unexpected multi-input project; corrupted or hand-edited fragment metadata; frontend/meta version mismatch.
Related errors
- expect PbNodeBody::Sink but got: {:?}
- expect PbNodeBody::StreamScan or PbNodeBody::Project but got
- expect PbNodeBody::StreamScan but got: {:?}
- expect PbNodeBody::Merge but got: {:?}
- expect PbNodeBody::Project but got: {:?}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/6508d4731a982169.
Report an issue: GitHub.