databendlabs/databend · error

not implemented: AggregateMeta does not support exchanging…

Error message

not implemented: AggregateMeta does not support exchanging between multiple nodes

What it means

`AggregateMeta::typetag_deserialize` is hard-coded to `unimplemented!()` because AggregateMeta block metadata cannot cross node boundaries — it is only valid within a single node's pipeline. Attempting to deserialize (exchange) this metadata panics. This is a designed limitation marking distributed exchange of partial aggregate state as unsupported.

Solutions

  1. Keep aggregation single-node (avoid distributed exchange of aggregate partial state) until support exists
  2. Implement typetag_deserialize/typetag_name for AggregateMeta so it can be serialized across nodes
  3. Use a metadata type designed for exchange (or strip AggregateMeta before serializing blocks for exchange)
  4. Wrap deserialization paths to convert this panic into a clear query error
Defensive patterns

Strategy: try-catch

Validate before calling

if matches!(meta.downcast_ref::<AggregateMeta>(), Some(_)) {
    // route to single-node path instead of exchange
}

Type guard

fn is_aggregate_meta(m: &dyn BlockMetaInfo) -> bool { m.typetag_name_matches("AggregateMeta") }

Try / catch

match std::panic::catch_unwind(|| serde_exchange::deserialize(block)) {
    Ok(v) => v,
    Err(_) => return Err(ErrorCode::Unimplemented("AggregateMeta cannot be exchanged between nodes")),
}

Prevention

When it happens

Trigger: Serializing/deserializing a block carrying AggregateMeta for a cluster data exchange (e.g. exchange/shuffle between nodes in a distributed aggregation plan).

Common situations: Distributed query setups where aggregate partial state is routed through flight/exchange channels; testing multi-node aggregation with this metadata attached.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/e2b805c81d1ce8b1. Report an issue: GitHub.

Appendix: source

Thrown at src/query/service/src/pipelines/processors/transforms/aggregator/aggregate_meta.rs:327

        match self {
            AggregateMeta::Partitioned { .. } => {
                f.debug_struct("AggregateMeta::Partitioned").finish()
            }
            AggregateMeta::Serialized { .. } => {
                f.debug_struct("AggregateMeta::Serialized").finish()
            }
            AggregateMeta::Spilled(_) => f.debug_struct("Aggregate::Spilled").finish(),
            AggregateMeta::BucketSpilled(_) => f.debug_struct("Aggregate::BucketSpilled").finish(),
            AggregateMeta::AggregatePayload(_) => {
                f.debug_struct("AggregateMeta:AggregatePayload").finish()
            }
        }
    }
}

impl BlockMetaInfo for AggregateMeta {
    fn typetag_deserialize(&self) {
        unimplemented!("AggregateMeta does not support exchanging between multiple nodes")
    }

    fn typetag_name(&self) -> &'static str {
        unimplemented!("AggregateMeta does not support exchanging between multiple nodes")
    }

    fn output_stats(&self) -> Option<BlockProfileStatistics> {
        match self {
            AggregateMeta::Serialized(payload) => Some(BlockProfileStatistics {
                rows: payload.data_block.num_rows(),
                bytes: payload.data_block.memory_size(),
            }),
            AggregateMeta::AggregatePayload(payload) => Some(BlockProfileStatistics {
                rows: payload.payload.len(),
                bytes: payload.payload.memory_size(),
            }),
            AggregateMeta::Partitioned { data, .. } => data.output_stats(),
            AggregateMeta::BucketSpilled(payload) => Some(BlockProfileStatistics {

View on GitHub (pinned to 288d84d76e)