{"record":{"id":"ab2b70709939c2aa","repo":"django/django","slug":"index-out-of-range-when-accessing-points-of-a-line","errorCode":null,"errorMessage":"Index out of range when accessing points of a line string: %s.","messagePattern":"Index out of range when accessing points of a line string: (.+?)\\.","errorType":"exception","errorClass":"IndexError","httpStatus":null,"severity":"error","filePath":"django/contrib/gis/gdal/geometries.py","lineNumber":657,"sourceCode":"class LineString(OGRGeometry):\n    def __getitem__(self, index):\n        \"Return the Point at the given index.\"\n        if 0 <= index < self.point_count:\n            x, y, z, m = c_double(), c_double(), c_double(), c_double()\n            capi.get_point(self.ptr, index, byref(x), byref(y), byref(z), byref(m))\n            if self.is_3d and self.is_measured:\n                return x.value, y.value, z.value, m.value\n            if self.is_3d:\n                return x.value, y.value, z.value\n            if self.is_measured:\n                return x.value, y.value, m.value\n            dim = self.coord_dim\n            if dim == 1:\n                return (x.value,)\n            elif dim == 2:\n                return (x.value, y.value)\n        else:\n            raise IndexError(\n                \"Index out of range when accessing points of a line string: %s.\" % index\n            )\n\n    def __len__(self):\n        \"Return the number of points in the LineString.\"\n        return self.point_count\n\n    @property\n    def tuple(self):\n        \"Return the tuple representation of this LineString.\"\n        return tuple(self[i] for i in range(len(self)))\n\n    coords = tuple\n\n    def _listarr(self, func):\n        \"\"\"\n        Internal routine that returns a sequence (list) corresponding with\n        the given function.","sourceCodeStart":639,"sourceCodeEnd":675,"githubUrl":"https://github.com/django/django/blob/ae25a40be07e8a749edf526df37c93e59d4a22c9/django/contrib/gis/gdal/geometries.py#L639-L675","documentation":"Raised as IndexError by LineString.__getitem__ when the requested index is outside [0, point_count) (geometries.py:657). It guards the underlying OGR get_point C call from an out-of-bounds read.","triggerScenarios":"Calling line[i] where i < 0 or i >= line.point_count; iterating with a hard-coded index larger than the actual vertex count; off-by-one when computing the last vertex.","commonSituations":"Parsing geometries of varying vertex counts and assuming a fixed length; index derived from user input without bounds checking; reverse iteration using positive indices.","solutions":["Bounds-check before indexing: if 0 <= i < len(line): ...","Use negative-safe iteration: for pt in line.tuple: ...","Cache len(line) / line.point_count and clamp the index."],"exampleFix":"// before\nlast = line[len(line)]  # off-by-one -> IndexError\n\n// after\nlast = line[len(line) - 1]","handlingStrategy":"validation","validationCode":"def safe_line_point(line, i):\n    if not (0 <= i < len(line)):\n        raise IndexError(f'vertex {i} out of range [0,{len(line)})')\n    return line[i]","typeGuard":"def is_valid_line_index(line, i) -> bool:\n    return isinstance(i, int) and 0 <= i < len(line)","tryCatchPattern":"try:\n    pt = line[i]\nexcept IndexError:\n    pt = None  # or clamp i to range","preventionTips":["Always bounds-check with len(line) before indexing a LineString.","Prefer iteration (for pt in line.tuple) over fixed-index access.","Compute the last index as len(line) - 1, not len(line)."],"tags":["gis","ogr","linestring","index-error","bounds"],"analyzedSha":"ae25a40be07e8a749edf526df37c93e59d4a22c9","analyzedAt":"2026-08-06T21:46:51.801Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}