quickwit-oss/tantivy · error
unexpected aggregation, expected term aggregation
Error message
unexpected aggregation, expected term aggregation
What it means
A panic in `into_final_bucket_result`: `IntermediateBucketResult::Terms` is being finalized with `req.agg.as_term().expect("unexpected aggregation, expected term aggregation")`, which fires when the request's aggregation is not a terms aggregation. The intermediate bucket result and the request definition disagree on aggregation type — an internal consistency violation rather than a user-input error.
Source
Thrown at src/aggregation/intermediate_agg_result.rs:694
limits,
)?;
let buckets = if histogram_req.keyed {
let mut bucket_map =
FxHashMap::with_capacity_and_hasher(buckets.len(), Default::default());
for bucket in buckets {
bucket_map.insert(bucket.key.to_string(), bucket);
}
BucketEntries::HashMap(bucket_map)
} else {
BucketEntries::Vec(buckets)
};
Ok(BucketResult::Histogram { buckets })
}
IntermediateBucketResult::Terms { buckets: terms } => terms.into_final_result(
req.agg
.as_term()
.expect("unexpected aggregation, expected term aggregation"),
req.sub_aggregation(),
limits,
),
IntermediateBucketResult::Filter {
doc_count,
sub_aggregations,
} => {
// Convert sub-aggregation results to final format
let final_sub_aggregations = sub_aggregations
.into_final_result(req.sub_aggregation().clone(), limits.clone())?;
Ok(BucketResult::Filter(FilterBucketResult {
doc_count,
sub_aggregations: final_sub_aggregations,
}))
}
IntermediateBucketResult::Composite { buckets } => {
let composite_req = req
.aggView on GitHub (pinned to b5d8deb80c)
Solutions
- Finalize with the exact request that produced the intermediate results.
- Ensure all nodes run compatible engine versions.
- Do not reorder or rewrite aggregation definitions before finalization.
- If you maintain the code, return an internal error via ok_or instead of expecting.
Example fix
// before
req.agg.as_term().expect("unexpected aggregation, expected term aggregation")
// after
req.agg.as_term()
.ok_or_else(|| crate::AggregationError::Internal("expected term agg".to_string()))? Defensive patterns
Strategy: validation
Validate before calling
fn is_term_agg(req: &Aggregation) -> bool {
matches!(req, Aggregation::Term(_))
}
// guard before finalizing terms intermediates Type guard
fn as_terms(req: &Aggregation) -> Option<&TermsAgg> {
if let Aggregation::Term(t) = req { Some(t) } else { None }
} Try / catch
let res = std::panic::catch_unwind(|| terms.into_final_result(req_agg, sub_agg, limits));
match res {
Ok(r) => r,
Err(_) => internal_error("expected term aggregation during finalization"),
} Prevention
- Never reuse intermediate aggregation results across different search requests.
- Ensure all nodes deserialize aggregation requests identically (same version).
- Test rolling upgrades for aggregation intermediate-format compatibility.
When it happens
Trigger: Finalizing a terms intermediate bucket result when the request resolved by aggregation path/id is not `Aggregation::Term` — e.g. distributed merge with mismatched aggregation trees, version skew, or intermediate results reused with a different request.
Common situations: Coordinator/node version mismatch in a cluster; incorrectly keyed caches of intermediate aggregation results; programmatic mutation of the request between search and finalization.
Related errors
- unexpected metric type
- unexpected aggregation, expected histogram aggregation
- unexpected aggregation, expected range aggregation
- unexpected aggregation, expected composite aggregation
- TermMissingAgg collector, but no missing found in agg req
AI-assisted analysis of quickwit-oss/tantivy@b5d8deb80c (2026-09-05).
Data as JSON: /api/errors/f1bf450a4696e995.
Report an issue: GitHub.