{"record":{"id":"82c80de21304693a","repo":"pola-rs/polars","slug":"cannot-use-positive-offset-on-a-negative-slice","errorCode":null,"errorMessage":"cannot use positive_offset() on a negative slice","messagePattern":"cannot use positive_offset\\(\\) on a negative slice","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/polars-utils/src/slice_enum.rs","lineNumber":42,"sourceCode":"            Slice::Positive { len, .. } => *len,\n            Slice::Negative { len, .. } => *len,\n        }\n    }\n\n    pub fn len_mut(&mut self) -> &mut usize {\n        match self {\n            Slice::Positive { len, .. } => len,\n            Slice::Negative { len, .. } => len,\n        }\n    }\n\n    /// Returns the offset of a positive slice.\n    ///\n    /// # Panics\n    /// Panics if `self` is [`Slice::Negative`]\n    pub fn positive_offset(&self) -> usize {\n        let Slice::Positive { offset, len: _ } = self.clone() else {\n            panic!(\"cannot use positive_offset() on a negative slice\");\n        };\n\n        offset\n    }\n\n    /// Returns the end position of the slice (offset + len).\n    ///\n    /// # Panics\n    /// Panics if self is negative.\n    pub fn end_position(&self) -> usize {\n        let Slice::Positive { offset, len } = self.clone() else {\n            panic!(\"cannot use end_position() on a negative slice\");\n        };\n\n        offset.saturating_add(len)\n    }\n\n    /// Returns the equivalent slice to apply from an offsetted position.","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/crates/polars-utils/src/slice_enum.rs#L24-L60","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the slice variant first: only call positive_offset() when the slice is Slice::Positive","Convert the negative slice to a positive one first (e.g. resolve it against the actual length)","Use a method that handles both variants, or match on the Slice enum yourself"],"exampleFix":"// before\nlet offset = slice.positive_offset();\n// after\nlet offset = match slice {\n    Slice::Positive { offset, .. } => offset,\n    Slice::Negative { offset, len } => /* resolve against sequence length */ 0,\n};","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def is_positive_slice(s: polars._utils.slice.Slice) -> bool:\n    return isinstance(s, ...) and not getattr(s, 'is_negative', False) # or match on Slice::Positive variant in Rust","tryCatchPattern":null,"preventionTips":["Resolve negative slices to positive ones immediately after parsing user input","Centralize slice-variant handling in one helper instead of calling positive_offset() ad hoc","Add debug_assert! / unit tests covering negative slice inputs"],"tags":["rust","panic","invalid-state","slices"],"backgroundTag":"invalid-state-transition","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}