{"record":{"id":"e8b5149f0e03b76f","repo":"vectordotdev/vector","slug":"bins-is-empty","errorCode":null,"errorMessage":"bins is empty","messagePattern":"bins is empty","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/sinks/util/statistic.rs","lineNumber":90,"sourceCode":"                    median,\n                    avg,\n                    sum,\n                    count: count as u64,\n                    quantiles,\n                }\n            }),\n        }\n    }\n}\n\n/// `bins` is a cumulative histogram\n/// We are using R-3 (without choosing the even integer in the case of a tie),\n/// it might be preferable to use a more common function, such as R-7.\n///\n/// List of quantile functions:\n/// <https://en.wikipedia.org/wiki/Quantile#Estimating_quantiles_from_a_sample>\nfn find_quantile(bins: &[Sample], p: f64) -> f64 {\n    let count = bins.last().expect(\"bins is empty\").rate;\n    find_sample(bins, (p * count as f64).round() as u32)\n}\n\n/// `bins` is a cumulative histogram\n/// Return the i-th smallest value,\n/// i starts from 1 (i == 1 mean the smallest value).\n/// i == 0 is equivalent to i == 1.\nfn find_sample(bins: &[Sample], i: u32) -> f64 {\n    let index = match bins.binary_search_by_key(&i, |sample| sample.rate) {\n        Ok(index) => index,\n        Err(index) => index,\n    };\n    bins[index].value\n}\n\npub fn validate_quantiles(quantiles: &[f64]) -> Result<(), ValidationError> {\n    if quantiles\n        .iter()","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/sinks/util/statistic.rs#L72-L108","documentation":"find_quantile implements R-3 quantile estimation over a cumulative histogram of samples. It calls bins.last().expect(\"bins is empty\") to read the total count from the final cumulative bin; if the sample slice is empty there is no last element and the expect panics. The function assumes at least one Sample was collected before any quantile is queried.","triggerScenarios":"Calling find_quantile (via from_samples) with an empty &[Sample] slice — i.e. a histogram built with zero observations, typically when an aggregation window produced no data.","commonSituations":"Computing p50/p95/p99 statistics in the aggregator over a time window where no events arrived (idle source, misconfigured metric tags, or a transform filtering everything out).","solutions":["Guard in from_samples: return early (f64::NAN or None) when samples is empty before calling find_quantile.","Ensure the histogram is only finalized when it contains at least one sample.","Fix upstream filters/windowing so the aggregation window is not empty when statistics are requested."],"exampleFix":"// before\nlet count = bins.last().expect(\"bins is empty\").rate;\n// after\nlet Some(last) = bins.last() else { return f64::NAN; };\nlet count = last.rate;","handlingStrategy":"validation","validationCode":"if samples.is_empty() { /* skip quantile computation */ }","typeGuard":"fn has_samples(bins: &[Sample]) -> bool { !bins.is_empty() }","tryCatchPattern":null,"preventionTips":["Only compute statistics for aggregation windows that received at least one event.","Return NaN/None from quantile helpers for empty input instead of panicking.","Add a unit test for from_samples with an empty sample list."],"tags":["rust","panic","statistics","empty-collection"],"backgroundTag":"empty-required-field","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}