oraios/serena · error · ValueError

Cannot insert after this symbol (not a function, class or me

Error message

Cannot insert after this symbol (not a function, class or method): {symbol}. Consider using insert_before_symbol instead.

What it means

insert_after_symbol appends code after a symbol's body. When `_find_unique_symbol` returns a symbol whose body equals just its name (i.e. it has no real body — typically a variable/constant or attribute, not a function/class/method), serena raises ValueError and suggests insert_before_symbol instead.

Source

Thrown at src/serena/code_editor.py:151

                continue
            else:
                break
        return cnt

    @classmethod
    def _count_trailing_newlines(cls, text: Reversible) -> int:
        return cls._count_leading_newlines(reversed(text))

    def insert_after_symbol(self, name_path: str, relative_file_path: str, body: str) -> None:
        """
        Inserts content after the symbol with the given name in the given file.
        """
        symbol = self._find_unique_symbol(name_path, relative_file_path)
        # Note: for body to be available, the symbol dto that the symbol instance is built from
        # must have been retrieved either with body or at least with location.
        # since _find_unique_symbol passes include_location=True, it works here
        if symbol.body == symbol.name:
            raise ValueError(
                f"Cannot insert after this symbol (not a function, class or method): {symbol}. Consider using insert_before_symbol instead."
            )

        # make sure body always ends with at least one newline
        if not body.endswith("\n"):
            body += "\n"

        pos = symbol.get_body_end_position_or_raise()

        # start at the beginning of the next line
        col = 0
        line = pos.line + 1

        # make sure a suitable number of leading empty lines is used (at least 0/1 depending on the symbol type,
        # otherwise as many as the caller wanted to insert)
        original_leading_newlines = self._count_leading_newlines(body)
        body = body.lstrip("\r\n")
        min_empty_lines = 0

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Use insert_before_symbol for the target symbol instead.
  2. Pick an adjacent function/class/method as the anchor, or use insert_at_line with an explicit line number.
  3. Verify the symbol kind (find_symbol and inspect kind) before calling insert_after_symbol.
  4. If it's truly a function/class whose body was misextracted, check the language server's symbol body support for that language.

Example fix

// before
editor.insert_after_symbol("MAX_RETRIES", "x = 1")  # ValueError
// after
editor.insert_at_line(3, "x = 1")  # or insert_before_symbol("MAX_RETRIES", ...)
Defensive patterns

Strategy: type-guard

Validate before calling

symbol = editor._find_unique_symbol(name_path, rel_path)  # or via find_symbol
kind = symbol.kind.name
if kind not in {'Function', 'Method', 'Class', 'Constructor'}:
    raise ValueError(f'{name_path} is a {kind}; use insert_before_symbol or insert_at_line')

Type guard

def has_body(symbol) -> bool:
    return bool(symbol.body) and symbol.body != symbol.name

if not has_body(symbol):
    # variable/attribute-like symbol: fall back to insert_before_symbol
    ...

Try / catch

try:
    editor.insert_after_symbol(name_path, snippet)
except ValueError as e:
    if 'not a function, class or method' in str(e):
        editor.insert_before_symbol(name_path, snippet)

Prevention

When it happens

Trigger: Calling insert_after_symbol(name_path, ...) on a variable, constant, field, or import — any symbol whose extracted body is just the name — rather than a function, class, or method with a body.

Common situations: Targeting `MY_CONST = 5` or a module-level variable after a refactor; pointing at a dataclass field; automating edits where the symbol kind wasn't checked first.

Related errors


AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29). Data as JSON: /api/errors/80ef540e647bb026. Report an issue: GitHub.