django/django · error · GEOSException

Geometry resulting from slice deletion was invalid.

Error message

Geometry resulting from slice deletion was invalid.

What it means

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.

Source

Thrown at django/contrib/gis/geos/linestring.py:132

        ndim = self._cs.dims
        hasz = self._cs.hasz  # I don't understand why these are different
        srid = self.srid

        # create a new coordinate sequence and populate accordingly
        cs = GEOSCoordSeq(capi.create_cs(length, ndim), z=hasz)
        for i, c in enumerate(items):
            cs[i] = c

        ptr = self._init_func(cs.ptr)
        if ptr:
            capi.destroy_geom(self.ptr)
            self.ptr = ptr
            if srid is not None:
                self.srid = srid
            self._post_init()
        else:
            # can this happen?
            raise GEOSException("Geometry resulting from slice deletion was invalid.")

    def _set_single(self, index, value):
        self._cs[index] = value

    def _checkdim(self, dim):
        if dim not in (2, 3):
            raise TypeError("Dimension mismatch.")

    # #### Sequence Properties ####
    @property
    def tuple(self):
        "Return a tuple version of the geometry from the coordinate sequence."
        return self._cs.tuple

    coords = tuple

    def _listarr(self, func):
        """

View on GitHub (pinned to ae25a40be0)

Solutions

  1. Inspect the replacement coordinates for minimum point count and validity before the slice assignment.
  2. Catch GEOSException and fall back to constructing a new LineString from the desired coords rather than mutating in place.
  3. Verify the GEOS library version is supported by this Django release.

Example fix

// before
ls[:] = new_coords  # raises 'Geometry resulting from slice deletion was invalid.'
// after
from django.contrib.gis.geos import LineString, GEOSException
try:
    ls[:] = new_coords
except GEOSException:
    ls = LineString(new_coords, srid=ls.srid)
Defensive patterns

Strategy: try-catch

Validate before calling

def safe_slice_assign(ls, new_coords):
    from django.contrib.gis.geos import LineString, GEOSException
    try:
        ls[:] = new_coords
        return ls
    except GEOSException:
        return LineString(new_coords, srid=ls.srid)

Try / catch

from django.contrib.gis.geos import GEOSException
try:
    ls[:] = new_coords
except GEOSException:
    ls = LineString(new_coords, srid=ls.srid)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of django/django@ae25a40be0 (2026-08-06). Data as JSON: /api/errors/5e3ef848b10bc299. Report an issue: GitHub.