oraios/serena · error · ValueError
Body start position is not defined for {self}
Error message
Body start position is not defined for {self} What it means
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.
Source
Thrown at src/serena/symbol.py:111
pass
@property
@abstractmethod
def body(self) -> str | None:
pass
@property
@abstractmethod
def name(self) -> str:
pass
def get_body_start_position_or_raise(self) -> PositionInFile:
"""
Get the start position of the symbol body, raising an error if it is not defined.
"""
pos = self.get_body_start_position()
if pos is None:
raise ValueError(f"Body start position is not defined for {self}")
return pos
def get_body_end_position_or_raise(self) -> PositionInFile:
"""
Get the end position of the symbol body, raising an error if it is not defined.
"""
pos = self.get_body_end_position()
if pos is None:
raise ValueError(f"Body end position is not defined for {self}")
return pos
@abstractmethod
def is_neighbouring_definition_separated_by_empty_line(self) -> bool:
"""
:return: whether a symbol definition of this symbol's kind is usually separated from the
previous/next definition by at least one empty line.
"""
View on GitHub (pinned to 7fcbca7e62)
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
Example fix
// before
symbol.replace_body(new_src) # may raise for body-less symbols
// after
if symbol.get_body_start_position() is not None:
symbol.replace_body(new_src) Defensive patterns
Strategy: type-guard
Validate before calling
if symbol.get_body_start_position() is None:
raise SkipSymbol(f"no body: {symbol.get_name_path()}") Type guard
def has_editable_body(symbol) -> bool:
return symbol.get_body_start_position() is not None and symbol.get_body_end_position() is not None Try / catch
try:
symbol.replace_body(new_src)
except ValueError as e:
if "Body start position is not defined" in str(e):
handle_bodyless_symbol(symbol)
else:
raise Prevention
- 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
When it happens
Trigger: 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).
Common situations: Editing generated or non-source symbols; multi-language repos where one language server reports incomplete ranges; operating on symbol references rather than definitions.
Related errors
- Body end position is not defined for {self}
- Body line numbers could not be determined for {self.get_name
- No symbol matching '{name_path_pattern}' found
- Found multiple {len(symbol_candidates)} symbols matching '{n
- FindSymbolTool returned no results
AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29).
Data as JSON: /api/errors/0b1366e48222b55b.
Report an issue: GitHub.