{"record":{"id":"5e3ef848b10bc299","repo":"django/django","slug":"geometry-resulting-from-slice-deletion-was-invalid","errorCode":null,"errorMessage":"Geometry resulting from slice deletion was invalid.","messagePattern":"Geometry resulting from slice deletion was invalid\\.","errorType":"exception","errorClass":"GEOSException","httpStatus":null,"severity":"error","filePath":"django/contrib/gis/geos/linestring.py","lineNumber":132,"sourceCode":"        ndim = self._cs.dims\n        hasz = self._cs.hasz  # I don't understand why these are different\n        srid = self.srid\n\n        # create a new coordinate sequence and populate accordingly\n        cs = GEOSCoordSeq(capi.create_cs(length, ndim), z=hasz)\n        for i, c in enumerate(items):\n            cs[i] = c\n\n        ptr = self._init_func(cs.ptr)\n        if ptr:\n            capi.destroy_geom(self.ptr)\n            self.ptr = ptr\n            if srid is not None:\n                self.srid = srid\n            self._post_init()\n        else:\n            # can this happen?\n            raise GEOSException(\"Geometry resulting from slice deletion was invalid.\")\n\n    def _set_single(self, index, value):\n        self._cs[index] = value\n\n    def _checkdim(self, dim):\n        if dim not in (2, 3):\n            raise TypeError(\"Dimension mismatch.\")\n\n    # #### Sequence Properties ####\n    @property\n    def tuple(self):\n        \"Return a tuple version of the geometry from the coordinate sequence.\"\n        return self._cs.tuple\n\n    coords = tuple\n\n    def _listarr(self, func):\n        \"\"\"","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/django/django/blob/ae25a40be07e8a749edf526df37c93e59d4a22c9/django/contrib/gis/geos/linestring.py#L114-L150","documentation":"A GEOSException raised inside LineString._set_list (linestring.py:132) as a defensive guard after a slice-based mutation (e.g. __setitem__/_set_slice routing through _set_list) when the rebuilt coordinate sequence yields a NULL GEOS pointer. The source comment 'can this happen?' indicates it is an unexpected-state sentinel: the rebuild produced coordinates that GEOS refused to turn into a LineString.","triggerScenarios":"Assigning a slice that replaces the whole geometry (ls[:] = [...]) and the replacement coordinates form an invalid LineString at the C level; mutating a LinearRing via slicing such that the result is geometrically degenerate; very rarely, a GEOS library memory or version issue producing NULL from create_linestring.","commonSituations":"Programmatic geometry editing where a slice assignment leaves < 2 distinct points or self-intersecting ring; concurrent modification of the underlying C object; GEOS version incompatibility.","solutions":["Inspect the replacement coordinates for minimum point count and validity before the slice assignment.","Catch GEOSException and fall back to constructing a new LineString from the desired coords rather than mutating in place.","Verify the GEOS library version is supported by this Django release."],"exampleFix":"// before\nls[:] = new_coords  # raises 'Geometry resulting from slice deletion was invalid.'\n// after\nfrom django.contrib.gis.geos import LineString, GEOSException\ntry:\n    ls[:] = new_coords\nexcept GEOSException:\n    ls = LineString(new_coords, srid=ls.srid)","handlingStrategy":"try-catch","validationCode":"def safe_slice_assign(ls, new_coords):\n    from django.contrib.gis.geos import LineString, GEOSException\n    try:\n        ls[:] = new_coords\n        return ls\n    except GEOSException:\n        return LineString(new_coords, srid=ls.srid)","typeGuard":null,"tryCatchPattern":"from django.contrib.gis.geos import GEOSException\ntry:\n    ls[:] = new_coords\nexcept GEOSException:\n    ls = LineString(new_coords, srid=ls.srid)","preventionTips":["Validate replacement coords have >= 2 distinct points before slice assignment.","Prefer constructing a fresh geometry over in-place slice mutation.","Verify GEOS library compatibility for the Django release."],"tags":["django","gis","geos","linestring","mutation","null-pointer"],"analyzedSha":"ae25a40be07e8a749edf526df37c93e59d4a22c9","analyzedAt":"2026-08-06T21:46:51.801Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}