databendlabs/databend · error
PartitionItem::BucketSpilled(_) => unreachable!()
Error message
PartitionItem::BucketSpilled(_) => unreachable!()
What it means
`AggregateMeta::serialize_mixed` panics when it encounters a `PartitionItem::BucketSpilled` entry. Mixed-mode serialization expects each partition to be either fully in-memory (Serialized) or an AggregatePayload; a bucket that was already spilled to disk must not be present in the data being serialized, so this indicates mixed-mode bookkeeping produced an invalid partition set.
Solutions
- Reduce memory pressure or disable/tune aggregation spilling settings so buckets do not spill unexpectedly in this code path
- Check whether the query uses features that mix spilled buckets with serialized payloads and avoid the affected combination
- Report a bug with the query and settings; the spill bookkeeping in aggregate_meta.rs needs to handle or reject BucketSpilled explicitly
- Upgrade Databend for spill-handling fixes in the aggregator
Example fix
// before
PartitionItem::BucketSpilled(_) => unreachable!(),
// after
PartitionItem::BucketSpilled(item) => return Err(ErrorCode::Internal(
format!("BucketSpilled item {} not supported in serialize_mixed", item.bucket))), Defensive patterns
Strategy: validation
Validate before calling
if data.iter().any(|i| matches!(i, PartitionItem::BucketSpilled(_))) { return Err(ErrorCode::Internal("BucketSpilled item in serialize_mixed input")); } Type guard
fn is_serializable(i: &PartitionItem) -> bool { !matches!(i, PartitionItem::BucketSpilled(_)) } Prevention
- Keep spilled buckets out of the mixed-mode serialize path by filtering or routing them to the spilled handler
- Track spill state in a dedicated structure so mixed serialization sees only in-memory partitions
- Add aggregator tests that combine spilling with distributed exchange
When it happens
Trigger: Serializing aggregate metadata that contains a `BucketSpilled` partition item — i.e. the aggregator spilled a bucket to disk but the spill/mixed-mode logic still handed the partition to `serialize_mixed`.
Common situations: Distributed aggregation with spilling enabled under memory pressure, where spill state and in-memory partition tracking get out of sync; bugs in spill-aware aggregation planning.
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
- AggregateMeta does not support exchanging between multiple…
- _ => unreachable!()
- not implemented
- not implemented: AggregateMeta does not support exchanging…
- Sum resulted in NaN
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/032d1fcc41decd39.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/pipelines/processors/transforms/aggregator/aggregate_meta.rs:227
BinaryType::from_data(row_group_column),
]);
return data_block.add_meta(Some(AggregateSerdeMeta::create_spilled(
bucket_num as isize,
)));
}
let mut buckets = Vec::with_capacity(data.len());
let mut payload_row_counts = Vec::with_capacity(data.len());
let mut payload_blocks = Vec::with_capacity(data.len());
for item in data {
let (bucket, block) = match item {
PartitionItem::Serialized(payload) => (payload.bucket, payload.data_block),
PartitionItem::AggregatePayload(payload) => {
(payload.bucket, payload.payload.aggregate_flush_all()?)
}
PartitionItem::BucketSpilled(_) => unreachable!(),
};
if block.num_rows() == 0 {
continue;
}
buckets.push(bucket);
payload_row_counts.push(block.num_rows());
payload_blocks.push(block);
}
if payload_blocks.is_empty() {
return Ok(DataBlock::empty());
}
let merged_block = DataBlock::concat(&payload_blocks)?;
merged_block.add_meta(Some(AggregateSerdeMeta::create_partitioned_payload(
buckets,
payload_row_counts,View on GitHub (pinned to 288d84d76e)