oraios/serena · error · ValueError
Body line numbers could not be determined for {self.get_name
Error message
Body line numbers could not be determined for {self.get_name_path()} What it means
get_body_line_numbers_or_raise converts the body start/end positions to 1-based line numbers and raises when either is None. The `apply` tool relies on it to print/return precise line ranges, so symbols without resolvable body ranges abort the operation.
Source
Thrown at src/serena/symbol.py:317
return PositionInFile(line=start_pos["line"], col=start_pos["character"])
def get_body_end_position(self) -> PositionInFile | None:
end_pos = self.body_end_position
if end_pos is None:
return None
return PositionInFile(line=end_pos["line"], col=end_pos["character"])
def get_body_line_numbers(self) -> tuple[int | None, int | None]:
start_pos = self.body_start_position
end_pos = self.body_end_position
start_line = start_pos["line"] if start_pos else None
end_line = end_pos["line"] if end_pos else None
return start_line, end_line
def get_body_line_numbers_or_raise(self) -> tuple[int, int]:
start_line, end_line = self.get_body_line_numbers()
if start_line is None or end_line is None:
raise ValueError(f"Body line numbers could not be determined for {self.get_name_path()}")
return start_line, end_line
@property
def line(self) -> int | None:
"""
:return: the line in which the symbol identifier is defined.
"""
if "selectionRange" in self.symbol_root:
return self.symbol_root["selectionRange"]["start"]["line"]
else:
# line is expected to be undefined for some types of symbols (e.g. SymbolKind.File)
return None
@property
def column(self) -> int | None:
if "selectionRange" in self.symbol_root:
return self.symbol_root["selectionRange"]["start"]["character"]
else:View on GitHub (pinned to 7fcbca7e62)
Solutions
- Fall back to get_body_line_numbers() and handle None explicitly in your own tooling
- Only apply to symbols with full body ranges (check get_body_start_position()/get_body_end_position() first)
- Switch/upgrade the language server for the file's language so ranges are populated
Example fix
// before
start, end = symbol.get_body_line_numbers_or_raise()
// after
start, end = symbol.get_body_line_numbers()
if start is None or end is None:
skip_or_relocate(symbol) Defensive patterns
Strategy: type-guard
Validate before calling
start, end = symbol.get_body_line_numbers()
if start is None or end is None:
raise SkipSymbol(f"line numbers unavailable for {symbol.get_name_path()}") Type guard
def has_line_numbers(symbol) -> bool:
s, e = symbol.get_body_line_numbers()
return s is not None and e is not None Try / catch
try:
result = tool.apply(...)
except ValueError as e:
if "Body line numbers could not be determined" in str(e):
fallback_to_manual_range(symbol)
else:
raise Prevention
- Verify the language server reports full ranges for the target language
- Skip module-level/alias symbols when using the apply tool
- Use the lenient get_body_line_numbers() in custom tooling and handle None
When it happens
Trigger: Running the apply (present_instructions / body edit) tool on a symbol whose get_body_line_numbers() returns (None, ...) — e.g. body-less constructs or language servers that don't supply selection ranges.
Common situations: Applying edits to imports, type aliases or expressions; language servers with incomplete range support for the active language; symbol looked up from a reference rather than its definition.
Related errors
- Body start position is not defined for {self}
- Body end position is not defined for {self}
- 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/19f9c6abb79e0b54.
Report an issue: GitHub.