{"record":{"id":"80ef540e647bb026","repo":"oraios/serena","slug":"cannot-insert-after-this-symbol-not-a-function-c","errorCode":null,"errorMessage":"Cannot insert after this symbol (not a function, class or method): {symbol}. Consider using insert_before_symbol instead.","messagePattern":"Cannot insert after this symbol \\(not a function, class or method\\): (.+?)\\. Consider using insert_before_symbol instead\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/code_editor.py","lineNumber":151,"sourceCode":"                continue\n            else:\n                break\n        return cnt\n\n    @classmethod\n    def _count_trailing_newlines(cls, text: Reversible) -> int:\n        return cls._count_leading_newlines(reversed(text))\n\n    def insert_after_symbol(self, name_path: str, relative_file_path: str, body: str) -> None:\n        \"\"\"\n        Inserts content after the symbol with the given name in the given file.\n        \"\"\"\n        symbol = self._find_unique_symbol(name_path, relative_file_path)\n        # Note: for body to be available, the symbol dto that the symbol instance is built from\n        # must have been retrieved either with body or at least with location.\n        # since _find_unique_symbol passes include_location=True, it works here\n        if symbol.body == symbol.name:\n            raise ValueError(\n                f\"Cannot insert after this symbol (not a function, class or method): {symbol}. Consider using insert_before_symbol instead.\"\n            )\n\n        # make sure body always ends with at least one newline\n        if not body.endswith(\"\\n\"):\n            body += \"\\n\"\n\n        pos = symbol.get_body_end_position_or_raise()\n\n        # start at the beginning of the next line\n        col = 0\n        line = pos.line + 1\n\n        # make sure a suitable number of leading empty lines is used (at least 0/1 depending on the symbol type,\n        # otherwise as many as the caller wanted to insert)\n        original_leading_newlines = self._count_leading_newlines(body)\n        body = body.lstrip(\"\\r\\n\")\n        min_empty_lines = 0","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/code_editor.py#L133-L169","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use insert_before_symbol for the target symbol instead.","Pick an adjacent function/class/method as the anchor, or use insert_at_line with an explicit line number.","Verify the symbol kind (find_symbol and inspect kind) before calling insert_after_symbol.","If it's truly a function/class whose body was misextracted, check the language server's symbol body support for that language."],"exampleFix":"// before\neditor.insert_after_symbol(\"MAX_RETRIES\", \"x = 1\")  # ValueError\n// after\neditor.insert_at_line(3, \"x = 1\")  # or insert_before_symbol(\"MAX_RETRIES\", ...)","handlingStrategy":"type-guard","validationCode":"symbol = editor._find_unique_symbol(name_path, rel_path)  # or via find_symbol\nkind = symbol.kind.name\nif kind not in {'Function', 'Method', 'Class', 'Constructor'}:\n    raise ValueError(f'{name_path} is a {kind}; use insert_before_symbol or insert_at_line')","typeGuard":"def has_body(symbol) -> bool:\n    return bool(symbol.body) and symbol.body != symbol.name\n\nif not has_body(symbol):\n    # variable/attribute-like symbol: fall back to insert_before_symbol\n    ...","tryCatchPattern":"try:\n    editor.insert_after_symbol(name_path, snippet)\nexcept ValueError as e:\n    if 'not a function, class or method' in str(e):\n        editor.insert_before_symbol(name_path, snippet)","preventionTips":["Check the symbol kind before insert_after_symbol; only functions/classes/methods have bodies.","Prefer insert_at_line with an explicit line number when anchoring near variables or constants.","When automating edits, resolve the symbol with find_symbol and branch on its kind."],"tags":["symbols","code-edit","validation"],"backgroundTag":"symbol-has-no-body","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}