pola-rs/polars · error

cannot use positive_offset() on a negative slice

Error message

cannot use positive_offset() on a negative slice

What it means

Slice::positive_offset() only returns an offset for a Slice::Positive; if the slice is Slice::Negative it panics. Negative slices (counting from the end) have no meaningful positive offset until converted.

Solutions

  1. Check the slice variant first: only call positive_offset() when the slice is Slice::Positive
  2. Convert the negative slice to a positive one first (e.g. resolve it against the actual length)
  3. Use a method that handles both variants, or match on the Slice enum yourself

Example fix

// before
let offset = slice.positive_offset();
// after
let offset = match slice {
    Slice::Positive { offset, .. } => offset,
    Slice::Negative { offset, len } => /* resolve against sequence length */ 0,
};
Defensive patterns

Strategy: type-guard

Type guard

def is_positive_slice(s: polars._utils.slice.Slice) -> bool:
    return isinstance(s, ...) and not getattr(s, 'is_negative', False) # or match on Slice::Positive variant in Rust

Prevention

When it happens

Trigger: Calling positive_offset() on a slice created as Slice::Negative, e.g. Slice::new with a negative length/offset input that produced the Negative variant.

Common situations: Code that assumes slices are always positive (e.g. after user-provided slice expressions like df[:-5]) then asks for an offset; API changes where negative slice support was added and old code paths weren't updated.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at crates/polars-utils/src/slice_enum.rs:42

            Slice::Positive { len, .. } => *len,
            Slice::Negative { len, .. } => *len,
        }
    }

    pub fn len_mut(&mut self) -> &mut usize {
        match self {
            Slice::Positive { len, .. } => len,
            Slice::Negative { len, .. } => len,
        }
    }

    /// Returns the offset of a positive slice.
    ///
    /// # Panics
    /// Panics if `self` is [`Slice::Negative`]
    pub fn positive_offset(&self) -> usize {
        let Slice::Positive { offset, len: _ } = self.clone() else {
            panic!("cannot use positive_offset() on a negative slice");
        };

        offset
    }

    /// Returns the end position of the slice (offset + len).
    ///
    /// # Panics
    /// Panics if self is negative.
    pub fn end_position(&self) -> usize {
        let Slice::Positive { offset, len } = self.clone() else {
            panic!("cannot use end_position() on a negative slice");
        };

        offset.saturating_add(len)
    }

    /// Returns the equivalent slice to apply from an offsetted position.

View on GitHub (pinned to fe841f959e)