{"record":{"id":"384d05dd4efe6f5d","repo":"Textualize/textual","slug":"index-index-r-does-not-correspond-to-a-location","errorCode":null,"errorMessage":"Index {index!r} does not correspond to a location in the document.","messagePattern":"Index (.+?) does not correspond to a location in the document\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/textual/document/_document.py","lineNumber":388,"sourceCode":"        return index\n\n    def get_location_from_index(self, index: int) -> Location:\n        \"\"\"Given a codepoint index in the document's text, returns the corresponding location.\n\n        Args:\n            index: The index in the document's text.\n\n        Returns:\n            The corresponding location.\n\n        Raises:\n            ValueError: If the index is doesn't correspond to a location in the document.\n        \"\"\"\n        error_message = (\n            f\"Index {index!r} does not correspond to a location in the document.\"\n        )\n        if index < 0 or index > len(self.text):\n            raise ValueError(error_message)\n\n        column_index = 0\n        newline_length = len(self.newline)\n        for line_index in range(self.line_count):\n            next_column_index = (\n                column_index + len(self.get_line(line_index)) + newline_length\n            )\n            if index < next_column_index:\n                return (line_index, index - column_index)\n            elif index == next_column_index:\n                return (line_index + 1, 0)\n            column_index = next_column_index\n\n        raise ValueError(error_message)\n\n    def get_line(self, index: int) -> str:\n        \"\"\"Returns the line with the given index from the document.\n","sourceCodeStart":370,"sourceCodeEnd":406,"githubUrl":"https://github.com/Textualize/textual/blob/06dbeef4bb70fb718236aa418ed658ef4667a126/src/textual/document/_document.py#L370-L406","documentation":"Document.get_location_from_index raises ValueError when the given string index is negative or beyond len(document.text). The index space is character offsets into the whole document text.","triggerScenarios":"Calling get_location_from_index(-1) or with an index past the end (e.g. len(text) + 1), often from arithmetic like index + offset that overruns.","commonSituations":"Cursor/selection computations in TextArea-derived widgets that add or subtract offsets without clamping; using byte lengths instead of character counts for unicode text.","solutions":["Clamp the index: max(0, min(index, len(document.text)))","Recompute indices from document.text length rather than external counters","For unicode, use character-based indices, not byte offsets"],"exampleFix":"# before\nloc = doc.get_location_from_index(index + len(inserted))\n# after\nloc = doc.get_location_from_index(min(index + len(inserted), len(doc.text)))","handlingStrategy":"validation","validationCode":"def clamped(doc, index: int) -> int:\n    return max(0, min(index, len(doc.text)))","typeGuard":"def valid_index(doc, index: int) -> bool:\n    return 0 <= index <= len(doc.text)","tryCatchPattern":"try:\n    loc = doc.get_location_from_index(index)\nexcept ValueError:\n    loc = (doc.line_count - 1, len(doc.get_line(doc.line_count - 1)))","preventionTips":["Clamp indices before calling","Use character counts, not byte lengths, for unicode","Recompute indices from doc.text after edits"],"tags":["textual","document","index","bounds","valueerror"],"backgroundTag":"index-out-of-bounds","analyzedSha":"06dbeef4bb70fb718236aa418ed658ef4667a126","analyzedAt":"2026-08-27T02:36:57.214Z","schemaVersion":2},"datasetVersion":"2026-08-27T03:17:27.898Z"}