rayon-rs/rayon · error
range start should be <= range end
Error message
range start {:?} should be <= range end {:?} What it means
Panic raised by the range-normalization helper simplify_range when the caller supplies a range whose start bound exceeds its end bound (after resolution against the collection length len). The function converts any RangeBounds into a plain Range<usize>; the start match accepts start <= len and the end match accepts end <= len, but a resulting start > end has no valid interpretation (an empty range cannot be represented here), so it panics. This is a caller-input validation guard: the faulty input is a range like 3..1 or ..0 with start beyond end. Reached via collection operations built on it, e.g. Drain.
Solutions
- Validate `start <= end` before calling the API (use `range.clone().next()` / assert)
- Use `Range::new(start.min(end), start.max(end))` style normalization
- Check whether the intended API is `drain(start..)` vs `drain(..end)` with swapped args
Example fix
// before vec.par_drain(hi..lo); // panics if hi > lo // after assert!(lo <= hi, "invalid range"); vec.par_drain(lo..hi);
Defensive patterns
Strategy: validation
Validate before calling
fn range_ordered(r: &std::ops::Range<usize>) -> bool { r.start <= r.end } Prevention
- Assert start <= end at range-construction sites
- Use a range-builder function that orders bounds
- Name parameters clearly to avoid swapped arguments
When it happens
Trigger: Calling drain/splice-style APIs with `Range` where start > end, e.g. `drain(10..3)`, often because variables were swapped or the range was computed from sorted positions that changed.
Common situations: Swapped arguments to a helper producing a range; reusing a range captured before the collection shrank; min/max mixups.
Related errors
- range start should be <= length
- range end should be <= length
- FIFO is empty
- The global thread pool has not been initialized.
- owner thread
AI-assisted analysis of rayon-rs/rayon@ee0a00bdb1 (2026-09-07).
Data as JSON: /api/errors/b45493772d9bde9e.
Report an issue: GitHub.
Appendix: source
Thrown at src/math.rs:18
use std::ops::{Bound, Range, RangeBounds};
/// Normalize arbitrary `RangeBounds` to a `Range`
pub(super) fn simplify_range(range: impl RangeBounds<usize>, len: usize) -> Range<usize> {
let start = match range.start_bound() {
Bound::Unbounded => 0,
Bound::Included(&i) if i <= len => i,
Bound::Excluded(&i) if i < len => i + 1,
bound => panic!("range start {bound:?} should be <= length {len}"),
};
let end = match range.end_bound() {
Bound::Unbounded => len,
Bound::Excluded(&i) if i <= len => i,
Bound::Included(&i) if i < len => i + 1,
bound => panic!("range end {bound:?} should be <= length {len}"),
};
if start > end {
panic!(
"range start {:?} should be <= range end {:?}",
range.start_bound(),
range.end_bound()
);
}
start..end
}
View on GitHub (pinned to ee0a00bdb1)