{"record":{"id":"3b17625af0eaba3b","repo":"risingwavelabs/risingwave","slug":"expect-pbnodebody-merge-but-got","errorCode":null,"errorMessage":"expect PbNodeBody::Merge but got: {:?}","messagePattern":"expect PbNodeBody::Merge but got: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/stream/stream_graph/fragment.rs","lineNumber":457,"sourceCode":"        )\n        .into());\n    };\n    let stream_scan_type = PbStreamScanType::try_from(scan.stream_scan_type).unwrap();\n    if stream_scan_type != PbStreamScanType::ArrangementBackfill {\n        return Err(anyhow!(\n            \"unsupported stream_scan_type for auto refresh schema: {:?}\",\n            stream_scan_type\n        )\n        .into());\n    }\n    let [merge_node, _batch_plan_node] = stream_scan_node.input.as_slice() else {\n        panic!(\n            \"the number of StreamScan inputs is not 2: {:?}\",\n            stream_scan_node.input\n        );\n    };\n    let NodeBody::Merge(_) = merge_node.node_body.as_ref().unwrap() else {\n        return Err(anyhow!(\n            \"expect PbNodeBody::Merge but got: {:?}\",\n            merge_node.node_body\n        )\n        .into());\n    };\n    Ok(())\n}\n\n/// Output mapping info after rewriting a `StreamScan` node.\nstruct ScanRewriteResult {\n    old_output_index_to_new_output_index: HashMap<u32, u32>,\n    new_output_index_by_column_id: HashMap<ColumnId, u32>,\n    output_fields: Vec<risingwave_pb::plan_common::Field>,\n}\n\n/// Append new columns to a sink/log-store column list with updated names/ids.\nfn extend_sink_columns(\n    sink_columns: &mut Vec<PbColumnCatalog>,","sourceCodeStart":439,"sourceCodeEnd":475,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/stream/stream_graph/fragment.rs#L439-L475","documentation":"The StreamScan of an arrangement backfill must have exactly two inputs: a Merge (fetching from the upstream fragment) and a batch plan node. This error fires when the first input's node body is not `PbNodeBody::Merge`, so the backfill scan's upstream linkage cannot be validated.","triggerScenarios":"`generate_streaming_job` -> `check_sink_fragments_support_refresh_schema` where `stream_scan_node.input[0].node_body` is not `PbNodeBody::Merge`.","commonSituations":"Internal graph-generation inconsistency; frontend/meta version mismatch producing a different StreamScan input layout; corrupted fragment metadata.","solutions":["Ensure frontend and meta binaries are the same version and retry the DDL.","Dump the fragment graph from meta logs and inspect the StreamScan inputs.","Restart the meta node to rebuild in-memory graph state.","If reproducible on aligned versions, file a RisingWave bug with the job definition."],"exampleFix":"// before\nlet NodeBody::Merge(_) = merge_node.node_body.as_ref().unwrap() else { ... };\n// after: accept the non-merge shape with a diagnostic\nlet Some(NodeBody::Merge(m)) = merge_node.node_body.as_ref() else {\n    return Err(anyhow!(\"backfill scan first input is {:?}, expected Merge\", merge_node.node_body).into());\n};","handlingStrategy":"validation","validationCode":"if !matches!(merge_node.node_body.as_ref(), Some(NodeBody::Merge(_))) {\n    return Err(\"backfill scan first input must be Merge\".into());\n}","typeGuard":"fn first_input_is_merge(scan_node: &StreamNode) -> bool {\n    matches!(\n        scan_node.input.first().and_then(|n| n.node_body.as_ref()),\n        Some(NodeBody::Merge(_))\n    )\n}","tryCatchPattern":null,"preventionTips":["Pin all cluster components to one RisingWave release.","Validate StreamScan input arity and bodies right after graph generation.","Retain fragment graph dumps in logs to accelerate bug reports."],"tags":["risingwave","streaming-graph","plan-validation","meta-node"],"backgroundTag":"unexpected-response-shape","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}