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

  1. Make all cluster nodes run the same version and rerun
  2. Verify the transform feeding this serializer only emits AggregateMeta::Partitioned blocks
  3. 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

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


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)