{"record":{"id":"72ed7356fe6e1ce4","repo":"quickwit-oss/tantivy","slug":"unexpected-aggregation-expected-range-aggregation","errorCode":null,"errorMessage":"unexpected aggregation, expected range aggregation","messagePattern":"unexpected aggregation, expected range aggregation","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/aggregation/intermediate_agg_result.rs","lineNumber":649,"sourceCode":"                            req.agg\n                                .as_range()\n                                .expect(\"unexpected aggregation, expected histogram aggregation\"),\n                            range_res.column_type,\n                            limits,\n                        )\n                    })\n                    .collect::<crate::Result<Vec<_>>>()?;\n\n                buckets.sort_by(|left, right| {\n                    left.from\n                        .unwrap_or(f64::MIN)\n                        .total_cmp(&right.from.unwrap_or(f64::MIN))\n                });\n\n                let is_keyed = req\n                    .agg\n                    .as_range()\n                    .expect(\"unexpected aggregation, expected range aggregation\")\n                    .keyed;\n                let buckets = if is_keyed {\n                    let mut bucket_map =\n                        FxHashMap::with_capacity_and_hasher(buckets.len(), Default::default());\n                    for bucket in buckets {\n                        bucket_map.insert(bucket.key.to_string(), bucket);\n                    }\n                    BucketEntries::HashMap(bucket_map)\n                } else {\n                    BucketEntries::Vec(buckets)\n                };\n                Ok(BucketResult::Range { buckets })\n            }\n            IntermediateBucketResult::Histogram {\n                is_date_agg,\n                buckets,\n            } => {\n                let histogram_req = &req","sourceCodeStart":631,"sourceCodeEnd":667,"githubUrl":"https://github.com/quickwit-oss/tantivy/blob/b5d8deb80c26924e6b007a5b1a7630f35ca64de4/src/aggregation/intermediate_agg_result.rs#L631-L667","documentation":"A panic in `into_final_bucket_result` when reading the `keyed` flag of a range aggregation: `req.agg.as_range().expect(\"unexpected aggregation, expected range aggregation\")` fails because the request's aggregation is not a range aggregation even though the intermediate result is. Like its siblings, this indicates the request definition and the intermediate bucket result have diverged.","triggerScenarios":"Finalizing range aggregation results when the request resolved via `req.agg` is not an `Aggregation::Range` — typically from agg-id mismatches in distributed result merging, or reusing intermediate results with a different request.","commonSituations":"Version-skewed cluster nodes producing/consuming different intermediate formats; incorrect caching of intermediate agg results; test or plugin code constructing mismatched (request, intermediate) pairs.","solutions":["Finalize with the same aggregation request that produced the intermediate results.","Keep engine versions consistent across all nodes handling the query.","Do not map or rewrite intermediate bucket results between requests.","If you maintain the code, convert the expect into a propagated internal error."],"exampleFix":"// before\nreq.agg.as_range().expect(\"unexpected aggregation, expected range aggregation\").keyed\n// after\nreq.agg.as_range()\n    .ok_or_else(|| crate::AggregationError::Internal(\"expected range agg\".to_string()))?.keyed","handlingStrategy":"validation","validationCode":"fn is_range_agg(req: &Aggregation) -> bool {\n    matches!(req, Aggregation::Range(_))\n}\n// guard before reading .keyed","typeGuard":"fn range_keyed(req: &Aggregation) -> Option<bool> {\n    if let Aggregation::Range(r) = req { Some(r.keyed) } else { None }\n}","tryCatchPattern":"let res = std::panic::catch_unwind(|| into_final_bucket_result(intermediate, &req, limits));\nmatch res {\n    Ok(b) => b,\n    Err(_) => internal_error(\"expected range aggregation during finalization\"),\n}","preventionTips":["Pass the original request object through to finalization.","Avoid replaying cached intermediate bucket results against different requests.","Keep node versions in lockstep during rolling upgrades."],"tags":["rust","panic","aggregation","type-mismatch","internal-invariant"],"backgroundTag":"aggregation-type-mismatch","analyzedSha":"b5d8deb80c26924e6b007a5b1a7630f35ca64de4","analyzedAt":"2026-09-05T13:20:51.521Z","contentChangedAt":"2026-09-05T13:20:51.521Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}