{"record":{"id":"73fd4d572fa5314d","repo":"oraios/serena","slug":"body-end-position-is-not-defined-for-self","errorCode":null,"errorMessage":"Body end position is not defined for {self}","messagePattern":"Body end position is not defined for (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/symbol.py","lineNumber":120,"sourceCode":"    def name(self) -> str:\n        pass\n\n    def get_body_start_position_or_raise(self) -> PositionInFile:\n        \"\"\"\n        Get the start position of the symbol body, raising an error if it is not defined.\n        \"\"\"\n        pos = self.get_body_start_position()\n        if pos is None:\n            raise ValueError(f\"Body start position is not defined for {self}\")\n        return pos\n\n    def get_body_end_position_or_raise(self) -> PositionInFile:\n        \"\"\"\n        Get the end position of the symbol body, raising an error if it is not defined.\n        \"\"\"\n        pos = self.get_body_end_position()\n        if pos is None:\n            raise ValueError(f\"Body end position is not defined for {self}\")\n        return pos\n\n    @abstractmethod\n    def is_neighbouring_definition_separated_by_empty_line(self) -> bool:\n        \"\"\"\n        :return: whether a symbol definition of this symbol's kind is usually separated from the\n            previous/next definition by at least one empty line.\n        \"\"\"\n\n\nclass NamePathComponent:\n    def __init__(self, name: str, overload_idx: int | None = None) -> None:\n        self.name = name\n        self.overload_idx = overload_idx\n\n    def __repr__(self) -> str:\n        if self.overload_idx is not None:\n            return f\"{self.name}[{self.overload_idx}]\"","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/symbol.py#L102-L138","documentation":"Strict counterpart of the body-start accessor: get_body_end_position_or_raise raises when the symbol's body end position is None. Used by replace_body, insert_after_symbol and delete_symbol, which need a valid end to compute the edit range.","triggerScenarios":"insert_after_symbol/replace_body/delete_symbol on symbols whose end position is unavailable (body-less constructs, incomplete language-server ranges).","commonSituations":"Same as body-start: non-definitional symbols, languages with partial range support, stale symbol handles after file edits.","solutions":["Verify get_body_end_position() is not None before the mutating call","Target only complete definitions (functions, classes, methods)","Re-resolve the symbol after prior edits since stale positions can invalidate ranges"],"exampleFix":"// before\nsymbol.insert_after_symbol(new_code)\n// after\nif symbol.get_body_end_position() is not None:\n    symbol.insert_after_symbol(new_code)","handlingStrategy":"type-guard","validationCode":"if symbol.get_body_end_position() is None:\n    raise SkipSymbol(f\"no end position: {symbol.get_name_path()}\")","typeGuard":"def has_editable_body(symbol) -> bool:\n    return symbol.get_body_start_position() is not None and symbol.get_body_end_position() is not None","tryCatchPattern":"try:\n    symbol.insert_after_symbol(new_code)\nexcept ValueError as e:\n    if \"Body end position is not defined\" in str(e):\n        handle_bodyless_symbol(symbol)\n    else:\n        raise","preventionTips":["Only insert/delete around complete definitions","Check both body start and end before any range-based edit","Re-resolve symbols after earlier edits to avoid stale ranges"],"tags":["serena","symbols","refactoring"],"backgroundTag":"symbol-body-position-undefined","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}