pola-rs/polars · error

slice index starts at

Error message

slice index starts at {start} but ends at {end}

What it means

slice_index_fail panics with 'slice index starts at {start} but ends at {end}' when start > end, i.e. an inverted range. This matches stdlib behavior and is reached through check_range when callers pass a range whose bounds are reversed.

Solutions

  1. Swap the bounds if inverted: (min(start,end), max(start,end))
  2. Validate start <= end before slicing and return an empty result if not
  3. Normalize ranges with RangeBounds helpers before calling the slicing API
  4. Check for variable-order bugs at the call site that built the range

Example fix

// before
let out = check_range(start..end, ..len);
// after
let (start, end) = if start > end { (end, start) } else { (start, end) };
let out = check_range(start..end, ..len);
Defensive patterns

Strategy: validation

Validate before calling

def ordered_range(start, end):
    if start > end:
        start, end = end, start
    return start, end

Prevention

When it happens

Trigger: Passing a range like 10..5 or an inclusive range where the inclusive start exceeds the inclusive end to any API that slices via check_range.

Common situations: Variables accidentally swapped at the call site; ranges built from descending sorts; computing [last..first] instead of [first..last] after reordering.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/8c59aad4ed182e26. Report an issue: GitHub.

Appendix: source

Thrown at crates/polars-utils/src/range.rs:14

use std::ops;

// Copied from the stdlib.
fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
    if start > len {
        panic!("range start index {start} out of range for slice of length {len}",)
    }

    if end > len {
        panic!("range end index {end} out of range for slice of length {len}",)
    }

    if start > end {
        panic!("slice index starts at {start} but ends at {end}",)
    }

    // Only reachable if the range was a `RangeInclusive` or a
    // `RangeToInclusive`, with `end == len`.
    panic!("range end index {end} out of range for slice of length {len}",)
}

#[must_use]
pub fn check_range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
where
    R: ops::RangeBounds<usize>,
{
    let len = bounds.end;
    let end = match range.end_bound() {
        ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
        // Cannot overflow because `end < len` implies `end < usize::MAX`.
        ops::Bound::Included(&end) => end + 1,

View on GitHub (pinned to fe841f959e)