{"record":{"id":"b679faabdd7ccafb","repo":"pola-rs/polars","slug":"negative-stop-is-not-supported-for-lazy-slices","errorCode":null,"errorMessage":"negative stop is not supported for lazy slices","messagePattern":"negative stop is not supported for lazy slices","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/_utils/slice.py","lineNumber":138,"sourceCode":"\n    def __init__(self, obj: LazyFrame) -> None:\n        self.obj = obj\n\n    def apply(self, s: slice) -> LazyFrame:\n        \"\"\"\n        Apply a slice operation.\n\n        Note that LazyFrame is designed primarily for efficient computation and does not\n        know its own length so, unlike DataFrame, certain slice patterns (such as those\n        requiring negative stop/step) may not be supported.\n        \"\"\"\n        start = s.start or 0\n        step = s.step or 1\n\n        # fail on operations that require length to do efficiently\n        if s.stop and s.stop < 0:\n            msg = \"negative stop is not supported for lazy slices\"\n            raise ValueError(msg)\n        if step < 0 and (start > 0 or s.stop is not None) and (start != s.stop):\n            if not (start > 0 > step and s.stop is None):\n                msg = \"negative stride is not supported in conjunction with start+stop\"\n                raise ValueError(msg)\n\n        # ---------------------------------------\n        # empty slice patterns\n        # ---------------------------------------\n        # [:0]\n        # [i:<=i]\n        # [i:>=i:-k]\n        if (step > 0 and (s.stop is not None and start >= s.stop)) or (\n            step < 0\n            and (s.start is not None and s.stop is not None and s.stop >= s.start >= 0)\n        ):\n            return self.obj.clear()\n\n        # ---------------------------------------","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/_utils/slice.py#L120-L156","documentation":"LazyPolarsSlice.apply (polars/_utils/slice.py:138) translates a slice into lazy operations without knowing frame length. A negative stop (lf[10:-5], lf[:-3]) would require resolving the height first, which is not possible efficiently on a LazyFrame, so it fails fast with this ValueError. Positive-stop slices and negative steps without start+stop are fine; a plain DataFrame accepts the same slice.","triggerScenarios":"lf[:-5]; lf[10:-2]; lf['a'][:-1] on a lazy column expression context; porting df[:-n] code to lazy pipelines.","commonSituations":"Converting eager pandas-like tail slicing to LazyFrame code; interactive exploration habits applied to lazy queries that will only be resolved at collect().","solutions":["Use explicit lazy methods: lf.limit(n) (head) and lf.tail(n) instead of negative-stop slices","Use a positive stop when the length is known: lf.slice(10, 90)","Collect first if you truly need Python slice semantics: lf.collect()[:-5]"],"exampleFix":"# before\nlf[:-5]        # negative stop unsupported lazily\n\n# after\nlf.tail(5)     # or lf.collect()[:-5]","handlingStrategy":"validation","validationCode":"def lazy_slice(lf, start, stop):\n    if stop is not None and stop < 0:\n        return lf.collect()[:stop].lazy()  # or lf.tail(-stop) for the common case\n    return lf[start:stop]","typeGuard":"def is_lazy_safe_slice(s: slice) -> bool:\n    return not (s.stop is not None and s.stop < 0)","tryCatchPattern":null,"preventionTips":["Replace negative-stop slices with lf.tail(n)/lf.limit(n)","Use lf.slice(start, length) with known positive bounds","Collect before slicing when Python slice semantics are genuinely needed"],"tags":["python","polars","lazyframe","slicing","valueerror"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}