{"record":{"id":"0b1366e48222b55b","repo":"oraios/serena","slug":"body-start-position-is-not-defined-for-self","errorCode":null,"errorMessage":"Body start position is not defined for {self}","messagePattern":"Body start position is not defined for (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/symbol.py","lineNumber":111,"sourceCode":"        pass\n\n    @property\n    @abstractmethod\n    def body(self) -> str | None:\n        pass\n\n    @property\n    @abstractmethod\n    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","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/symbol.py#L93-L129","documentation":"Some symbols (e.g. certain language constructs) have no defined body start position. get_body_start_position_or_raise is the strict variant used by body-rewriting operations (replace_body, insert_before_symbol, delete_symbol) and raises this ValueError when the underlying get_body_start_position returns None.","triggerScenarios":"Calling replace_body/insert_before_symbol/delete_symbol on a symbol whose language-server data lacks a body start (e.g. interface members, some imports, expressions without bodies in certain languages).","commonSituations":"Editing generated or non-source symbols; multi-language repos where one language server reports incomplete ranges; operating on symbol references rather than definitions.","solutions":["Check get_body_start_position() for None before calling the _or_raise variants or the edit tools","Restrict edits to symbols with a concrete body (functions/classes/methods with definitions)","Refresh the symbol from the language server in case of stale index data"],"exampleFix":"// before\nsymbol.replace_body(new_src)  # may raise for body-less symbols\n// after\nif symbol.get_body_start_position() is not None:\n    symbol.replace_body(new_src)","handlingStrategy":"type-guard","validationCode":"if symbol.get_body_start_position() is None:\n    raise SkipSymbol(f\"no body: {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.replace_body(new_src)\nexcept ValueError as e:\n    if \"Body start position is not defined\" in str(e):\n        handle_bodyless_symbol(symbol)\n    else:\n        raise","preventionTips":["Filter edit targets to functions/classes/methods with concrete bodies","Guard with get_body_start_position() before body-rewriting tools","Refresh symbols from the language server before editing"],"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"}