{"record":{"id":"31da7663f7910c6e","repo":"oraios/serena","slug":"invalidtextlocationerror","errorCode":null,"errorMessage":"InvalidTextLocationError","messagePattern":"InvalidTextLocationError","errorType":"validation","errorClass":"InvalidTextLocationError","httpStatus":null,"severity":"error","filePath":"src/solidlsp/ls_utils.py","lineNumber":143,"sourceCode":"            self.line_start_idx = newline_end_idx\n        else:\n            self.idx = self._len\n            self.col = self._len - self.line_start_idx\n            self.is_newline = False\n        return True\n\n    def step_to(self, line: int, col: int):\n        \"\"\"\n        Steps through the text until the given line and column are reached, or until the end of the text is reached.\n\n        :param line: the 0-based line number to step to\n        :param col: the 0-based column number to step to\n        \"\"\"\n        while self.line < line:\n            if not self.step_line():\n                break\n        if self.line != line:\n            raise InvalidTextLocationError\n        self.idx += col\n        self.col = col\n\n    def process_all(self):\n        \"\"\"\n        Processes all characters in the text, updating the line and column numbers accordingly.\n        \"\"\"\n        while self.step_line():\n            pass\n\n    def get_last_line(self, with_end: bool) -> str:\n        \"\"\"\n        Returns the last line processed, optionally including the newline character(s) at the end\n        \"\"\"\n        start_idx = self.prev_line_start_idx\n        end_idx = self.prev_line_end_idx if not with_end else self.line_start_idx\n        return self._chars[start_idx:end_idx]\n","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/ls_utils.py#L125-L161","documentation":"InvalidTextLocationError raised by TextStepper.step_to (src/solidlsp/ls_utils.py:143) when the requested line number cannot be reached by stepping through the text — i.e. the target line exceeds the number of lines in the document.","triggerScenarios":"Calling step_to(line, col) (directly or via delete_symbol) with a line index beyond the end of the text, typically because a stale position was cached before the file was edited/shortened.","commonSituations":"Positions computed against an older file version then reused after edits; off-by-one or 1-based vs 0-based line confusion; parsing a document that changed on disk.","solutions":["Clamp/validate line and col against the text's actual line count before calling.","Recompute positions from the current file contents instead of stale cached values.","Confirm consistent 0-based line/column conventions."],"exampleFix":"// before\nstepper.step_to(500, 0)  # file has only 120 lines\n// after\nlines = text.splitlines()\nif line < len(lines):\n    stepper.step_to(line, col)","handlingStrategy":"validation","validationCode":"def line_exists(text: str, line: int) -> bool:\n    return 0 <= line < len(text.splitlines())","typeGuard":"def valid_position(text: str, line: int, col: int) -> bool:\n    lines = text.splitlines()\n    return 0 <= line < len(lines) and 0 <= col <= len(lines[line])","tryCatchPattern":"try:\n    stepper.step_to(line, col)\nexcept InvalidTextLocationError:\n    line = len(text.splitlines()) - 1\n    stepper.step_to(line, col)","preventionTips":["Clamp positions to the current document bounds","Recompute positions after every file edit — never reuse stale ones","Standardize on 0-based line/col everywhere"],"tags":["text-location","bounds","ls-utils"],"backgroundTag":"text-location-out-of-range","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}