risingwavelabs/risingwave · error
sink with auto schema change should have only 1 fragment, bu
Error message
sink with auto schema change should have only 1 fragment, but got {:?} What it means
`check_sink_fragments_support_refresh_schema` verifies that a sink with automatic schema change (schema refresh) consists of exactly one fragment, since schema-evolution handling is only implemented for single-fragment sinks. If the generated sink job has multiple fragments, creation fails with the fragment count reported.
Source
Thrown at src/meta/src/stream/stream_graph/fragment.rs:401
fn clone_fragment(fragment: &Fragment, id_generator_manager: &IdGeneratorManager) -> Fragment {
let fragment_id = GlobalFragmentIdGen::new(id_generator_manager, 1)
.to_global_id(0)
.as_global_id();
Fragment {
fragment_id,
fragment_type_mask: fragment.fragment_type_mask,
distribution_type: fragment.distribution_type,
state_table_ids: fragment.state_table_ids.clone(),
maybe_vnode_count: fragment.maybe_vnode_count,
nodes: fragment.nodes.clone(),
}
}
pub fn check_sink_fragments_support_refresh_schema(
fragments: &BTreeMap<FragmentId, Fragment>,
) -> MetaResult<()> {
if fragments.len() != 1 {
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!(View on GitHub (pinned to 6469eb736d)
Solutions
- Disable auto schema change on the sink (` = false`) if multi-fragment topology is required.
- Simplify the sink definition so it plans into a single fragment (remove extra transformations between source and sink).
- Check the sink connector's plan generation for why multiple fragments are produced and use the supported single-fragment layout.
Example fix
// before CREATE SINK s FROM mv WITH (connector = 'iceberg', auto_schema_change = true); -- plans to 2 fragments // after CREATE SINK s FROM mv WITH (connector = 'iceberg'); -- or ensure single-fragment plan with auto_schema_change = true
Defensive patterns
Strategy: validation
Validate before calling
-- SQL: check sink plan fragment count before enabling auto schema change -- EXPLAIN CREATE SINK ... ; ensure a single sink fragment when auto_schema_change = true
Try / catch
// Rust: result of generate_streaming_job
match generate_streaming_job(...) {
Ok(job) => job,
Err(e) if e.to_string().contains("should have only 1 fragment") => {
Err(anyhow!("disable auto schema change or simplify sink to one fragment: {e:#}"))
}
Err(e) => Err(e),
} Prevention
- Enable auto schema change only on sinks known to plan into one fragment.
- Check EXPLAIN output for fragment count before enabling schema refresh.
- Keep sink definitions simple (avoid extra transformations) when using auto_schema_change.
When it happens
Trigger: Creating a sink with auto schema change enabled whose streaming job plans into more than one fragment (`check_sink_fragments_support_refresh_schema`, fragment.rs:401, called from `generate_streaming_job`).
Common situations: Sinks with complex downstream transformations (e.g. with extra operators forcing multiple fragments) combined with `auto_schema_change = true`; Iceberg sinks with connectors that split the plan into several fragments; older/newer frontend behavior differences around sink fragmentation.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- only iceberg table can be altered as sink
- No allow_alter_on_fly fields registered for sink: {sink_name
- Field '{field}' is not allowed to be altered on the fly for
- `commit_checkpoint_interval` must be greater than 0
- only append-only delta lake sink is supported
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/4e00082df9f0e037.
Report an issue: GitHub.