databendlabs/databend · error

unreachable!()

Error message

unreachable!()

What it means

TransformAggregateSerializer::transform_input_data expects every non-empty input block to carry AggregateMeta::AggregatePayload so it can build a SerializeAggregateStream. If take_meta/downcast fails, the code calls unreachable!(), aborting because the serializer was fed a block shape it cannot serialize. It is a pipeline-internal invariant check, not user input validation.

Solutions

  1. Ensure all cluster nodes run the same Databend version and rerun the query
  2. Inspect the upstream transform feeding TransformAggregateSerializer to confirm it emits AggregatePayload meta
  3. If a custom pipeline is involved, only pass blocks with AggregateMeta::AggregatePayload to this serializer
  4. File a bug with query profile/plan if reproducible on identical versions
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check before the serializer transform
fn has_aggregate_payload(block: &DataBlock) -> bool {
    block.get_meta()
        .and_then(AggregateMeta::downcast_ref_from)
        .map(|m| matches!(m, AggregateMeta::AggregatePayload(_)))
        .unwrap_or(false)
}

Type guard

fn as_aggregate_payload(m: Option<&Arc<DataBlockMeta>>) -> Option<&AggregatePayload> {
    m.and_then(AggregateMeta::downcast_ref_from)
        .and_then(|m| match m {
            AggregateMeta::AggregatePayload(p) => Some(p),
            _ => None,
        })
}

Try / catch

match res {
    Err(e) if e.message().contains("unreachable") && pipeline_stage == "aggregate_serializer" => {
        // abort query, verify node versions, file bug with stack trace
    }
    ...
}

Prevention

When it happens

Trigger: event() -> transform_input_data receives a block whose meta is not AggregateMeta::AggregatePayload (e.g. it is Partitioned, spilled meta, or empty-with-wrong-meta), usually after pipeline rewiring, mixed cluster versions, or a bug in the transform upstream that attaches the wrong meta variant.

Common situations: Rolling upgrades with mismatched node versions exchanging aggregate payloads; custom transforms inserted between partial aggregation and the serializer; regressions from refactoring AggregateMeta enum 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/f858bccc60ef88c7. Report an issue: GitHub.

Appendix: source

Thrown at src/query/service/src/pipelines/processors/transforms/aggregator/serde/transform_aggregate_serializer.rs:123

            if self.output_data.is_none() {
                self.input_data = None;
            }
        }

        Ok(())
    }
}

impl TransformAggregateSerializer {
    fn transform_input_data(&mut self, mut data_block: DataBlock) -> Result<Event> {
        debug_assert!(data_block.is_empty());

        let Some(AggregateMeta::AggregatePayload(p)) = data_block
            .take_meta()
            .and_then(AggregateMeta::downcast_from)
        else {
            unreachable!()
        };

        self.input_data = Some(SerializeAggregateStream::create(&self.params, p));
        Ok(Event::Sync)
    }
}

pub struct SerializeAggregateStream {
    _params: Arc<AggregatorParams>,
    payload: AggregatePayload,
    flush_state: PayloadFlushState,
    end_iter: bool,
    nums: usize,
}

unsafe impl Send for SerializeAggregateStream {}

unsafe impl Sync for SerializeAggregateStream {}

View on GitHub (pinned to 288d84d76e)