vectordotdev/vector · error
bins is empty
Error message
bins is empty
What it means
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.
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.
Example fix
// before
let count = bins.last().expect("bins is empty").rate;
// after
let Some(last) = bins.last() else { return f64::NAN; };
let count = last.rate; Defensive patterns
Strategy: validation
Validate before calling
if samples.is_empty() { /* skip quantile computation */ } Type guard
fn has_samples(bins: &[Sample]) -> bool { !bins.is_empty() } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- a record with a next ID must have an event count
- a valid HTTP/1 URI is valid as an HTTP URI
- a validated HTTP endpoint is a valid `http 1` URI
- all json-file keys should be matched
- allowed_lateness_ms validated to fit in i64 in…
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/e8b5149f0e03b76f.
Report an issue: GitHub.
Appendix: source
Thrown at src/sinks/util/statistic.rs:90
median,
avg,
sum,
count: count as u64,
quantiles,
}
}),
}
}
}
/// `bins` is a cumulative histogram
/// We are using R-3 (without choosing the even integer in the case of a tie),
/// it might be preferable to use a more common function, such as R-7.
///
/// List of quantile functions:
/// <https://en.wikipedia.org/wiki/Quantile#Estimating_quantiles_from_a_sample>
fn find_quantile(bins: &[Sample], p: f64) -> f64 {
let count = bins.last().expect("bins is empty").rate;
find_sample(bins, (p * count as f64).round() as u32)
}
/// `bins` is a cumulative histogram
/// Return the i-th smallest value,
/// i starts from 1 (i == 1 mean the smallest value).
/// i == 0 is equivalent to i == 1.
fn find_sample(bins: &[Sample], i: u32) -> f64 {
let index = match bins.binary_search_by_key(&i, |sample| sample.rate) {
Ok(index) => index,
Err(index) => index,
};
bins[index].value
}
pub fn validate_quantiles(quantiles: &[f64]) -> Result<(), ValidationError> {
if quantiles
.iter()View on GitHub (pinned to bdb87aeaa4)