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

  1. Validate `start <= end` before calling the API (use `range.clone().next()` / assert)
  2. Use `Range::new(start.min(end), start.max(end))` style normalization
  3. 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

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


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)