databendlabs/databend · error
unexpected aggregate meta
Error message
unexpected aggregate meta
What it means
TransformExchangeAggregateSerializer serializes AggregateMeta::Partitioned payloads for exchange and only matches the Partitioned variant; any other AggregateMeta variant hits unreachable!("unexpected aggregate meta"). It asserts that only partitioned aggregate meta ever reaches this exchange serializer.
Solutions
- Make all cluster nodes run the same version and rerun
- Verify the transform feeding this serializer only emits AggregateMeta::Partitioned blocks
- Replace with a descriptive internal error to aid debugging and file an issue with the query profile
Example fix
// before
_ => unreachable!("unexpected aggregate meta"),
// after
meta => {
return Err(ErrorCode::Internal(format!(
"unexpected aggregate meta in exchange serializer: {meta:?}"
)));
} Defensive patterns
Strategy: try-catch
Validate before calling
fn is_partitioned(m: Option<&Arc<DataBlockMeta>>) -> bool {
m.and_then(AggregateMeta::downcast_ref_from)
.map(|m| matches!(m, AggregateMeta::Partitioned { .. }))
.unwrap_or(false)
} Type guard
fn partitioned_meta(m: Option<&Arc<DataBlockMeta>>) -> Option<(&Option<isize>, &PartitionedData)> {
m.and_then(AggregateMeta::downcast_ref_from)
.and_then(|m| match m {
AggregateMeta::Partitioned { bucket, data } => Some((bucket, data)),
_ => None,
})
} Try / catch
match res {
Err(e) if e.message().contains("unexpected aggregate meta") || panic_in("TransformExchangeAggregateSerializer") => {
// verify version skew, abort and report with query profile
}
...
} Prevention
- Ensure only the partitioned-aggregate pipeline feeds the shuffle exchange serializer
- Match cluster versions across all nodes
- Convert such unreachable! sites into typed ErrorCode::Internal for debuggability
- Add tests pinning AggregateMeta variants accepted by the serializer
When it happens
Trigger: transform() receives a block whose meta is AggregateMeta but not AggregateMeta::Partitioned (e.g. bare AggregatePayload or spilled meta), due to upstream pipeline mis-wiring, mixed node versions, or a regression in the partial aggregate transform.
Common situations: Rolling-upgrade version skew between nodes; custom pipelines attaching non-partitioned aggregate meta to blocks entering the shuffle exchange; bugs after refactoring AggregateMeta variants.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Internal, AggregateBucketScatter only recv Partitioned…
- _ => unreachable!()
- unreachable!()
- block_meta_ref is ExchangeDeserializeMeta
- [TRANSFORM-AGGREGATOR] Invalid hash table state during…
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/be32611f9abfc314.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/pipelines/processors/transforms/aggregator/serde/transform_exchange_aggregate_serializer.rs:194
StringType::from_data(location_column),
BinaryType::from_data(row_group_column),
]);
data_block.add_meta(Some(AggregateSerdeMeta::create_spilled(
bucket_num as isize,
)))?
}
PartitionedData::Mixed(data) => PartitionItem::serialize_mixed(data)?,
data => {
return Err(ErrorCode::Internal(format!(
"Partitioned meta cannot be serialized from this payload batch: {data:?}"
)));
}
};
let serialized = serialize_block(-1, data_block, &self.options)?;
serialized_blocks.push(serialized);
}
_ => unreachable!("unexpected aggregate meta"),
};
}
Ok(vec![DataBlock::empty_with_meta(
ExchangeShuffleMeta::create(serialized_blocks),
)])
}
}
View on GitHub (pinned to 288d84d76e)