{"record":{"id":"f7ca42d8df3547fa","repo":"databendlabs/databend","slug":"unreachable-f7ca42","errorCode":null,"errorMessage":"_ => unreachable!()","messagePattern":"_ => unreachable!\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/service/src/pipelines/processors/transforms/aggregator/serde/transform_deserializer.rs","lineNumber":233,"sourceCode":"                    return Ok(vec![DataBlock::empty_with_meta(partitioned)]);\n                }\n            }\n            other => Err(ErrorCode::Internal(format!(\n                \"Unknown aggregate serde meta type {other}\"\n            ))),\n        }\n    }\n}\n\nimpl TransformDeserializer {\n    fn transform_exchange_meta(\n        &mut self,\n        mut meta: ExchangeDeserializeMeta,\n    ) -> Result<Vec<DataBlock>> {\n        match meta.packet.pop().unwrap() {\n            DataPacket::FragmentData(v) => self.recv_data(meta.packet, v),\n            DataPacket::ErrorCode(err) => Err(err),\n            _ => unreachable!(),\n        }\n    }\n}\n\nimpl AccumulatingTransform for TransformDeserializer {\n    const NAME: &'static str = \"TransformDeserializer\";\n\n    fn transform(&mut self, mut data_block: DataBlock) -> Result<Vec<DataBlock>> {\n        if let Some(block_meta_ref) = data_block.get_meta() {\n            if ExchangeDeserializeMeta::downcast_ref_from(block_meta_ref).is_some() {\n                let block_meta = data_block.take_meta().unwrap();\n                let Some(meta) = ExchangeDeserializeMeta::downcast_from(block_meta) else {\n                    unreachable!(\"block_meta_ref is ExchangeDeserializeMeta\");\n                };\n\n                if data_block.num_rows() != 0 {\n                    return Err(ErrorCode::Internal(\"DataBlockMeta has rows\"));\n                }","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/service/src/pipelines/processors/transforms/aggregator/serde/transform_deserializer.rs#L215-L251","documentation":"TransformDeserializer::transform_exchange_meta unwraps packets from an ExchangeDeserializeMeta and handles only FragmentData and ErrorCode variants; anything else triggers unreachable!(). It encodes the invariant that exchange DataPackets between aggregation fragments contain only data fragments or error codes. Receiving a different packet kind means protocol mismatch between sender and receiver.","triggerScenarios":"transform() processes an ExchangeDeserializeMeta whose packet vector contains a DataPacket variant other than FragmentData/ErrorCode (e.g. a control packet) — typically from mixed-version clusters or a sender pipeline stage emitting unsupported packet types.","commonSituations":"Cluster nodes on different versions exchanging serialized fragments; bugs in the exchange sender after DataPacket enum gained new variants without updating the deserializer; custom exchange implementations.","solutions":["Align Databend versions across all nodes and retry the query","Check whether the sender side emits a new DataPacket variant the receiver doesn't handle (version skew)","File a bug if reproducible on matching versions, including the query that triggered it"],"exampleFix":"// before\nmatch meta.packet.pop().unwrap() {\n    DataPacket::FragmentData(v) => self.recv_data(meta.packet, v),\n    DataPacket::ErrorCode(err) => Err(err),\n    _ => unreachable!(),\n}\n// after\nmatch meta.packet.pop().unwrap() {\n    DataPacket::FragmentData(v) => self.recv_data(meta.packet, v),\n    DataPacket::ErrorCode(err) => Err(err),\n    other => Err(ErrorCode::Internal(format!(\"unexpected exchange packet: {other:?}\"))),\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_handled_packet(p: &DataPacket) -> bool {\n    matches!(p, DataPacket::FragmentData(_) | DataPacket::ErrorCode(_))\n}","tryCatchPattern":"match res {\n    Err(e) if e.message().contains(\"unreachable\") => {\n        // check for mixed cluster versions; re-run after upgrade completes\n    }\n    ... \n}","preventionTips":["Complete rolling upgrades fully before issuing distributed aggregation queries","When adding DataPacket variants, update every match site including TransformDeserializer","Prefer typed Internal errors over unreachable! for protocol messages","Add exchange round-trip tests covering all DataPacket variants"],"tags":["internal","distributed-query","exchange","unreachable"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}