{"record":{"id":"0c909213c760ec68","repo":"oraios/serena","slug":"cannot-extract-symbols-from-file-relative-path","errorCode":null,"errorMessage":"Cannot extract symbols from file {relative_path}. Active language servers: {[l.value for l in self.agent.get_active_language_server_ids()]}","messagePattern":"Cannot extract symbols from file (.+?)\\. Active language servers: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/tools/symbol_tools.py","lineNumber":109,"sourceCode":"        return self._limit_length(result_json_str, max_answer_chars, shortened_result_factories=shortened_results)\n\n    def get_symbol_overview(self, relative_path: str, depth: int = 0) -> list[LanguageServerSymbol.OutputDict]:\n        \"\"\"\n        :param relative_path: relative path to a source file\n        :param depth: the depth up to which descendants shall be retrieved\n        :return: a list of symbol dictionaries representing the symbol overview of the file\n        \"\"\"\n        symbol_retriever = self.create_language_server_symbol_retriever()\n\n        # The symbol overview is capable of working with both files and directories,\n        # but we want to ensure that the user provides a file path.\n        file_path = os.path.join(self.project.project_root, relative_path)\n        if not os.path.exists(file_path):\n            raise FileNotFoundError(f\"File or directory {relative_path} does not exist in the project.\")\n        if os.path.isdir(file_path):\n            raise ValueError(f\"Expected a file path, but got a directory path: {relative_path}. \")\n        if not symbol_retriever.can_analyze_file(relative_path):\n            raise ValueError(\n                f\"Cannot extract symbols from file {relative_path}. Active language servers: {[l.value for l in self.agent.get_active_language_server_ids()]}\"\n            )\n\n        symbols = symbol_retriever.get_symbol_overview(relative_path)[relative_path]\n\n        def child_inclusion_predicate(s: LanguageServerSymbol) -> bool:\n            return not s.is_low_level()\n\n        symbol_dicts = []\n        for symbol in symbols:\n            symbol_dicts.append(\n                symbol.to_dict(\n                    name_path=False,\n                    name=True,\n                    depth=depth,\n                    kind=True,\n                    relative_path=False,\n                    location=False,","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/tools/symbol_tools.py#L91-L127","documentation":"Even for an existing file, the active language server(s) may not be able to analyze its type. When symbol_retriever.can_analyze_file returns False, the tool raises ValueError listing the currently active language servers so the caller can see the mismatch.","triggerScenarios":"Requesting symbols from a file with an extension not covered by any active language server (e.g. a .json, .txt, or a language whose LS isn't enabled); a language server failed to start so its languages are inactive.","commonSituations":"Pointing symbol tools at config/docs files; missing language server configuration for the project's language; LS crashed at startup so can_analyze_file fails for otherwise supported files.","solutions":["Point the tool at a source file of a language with an active language server","Configure/enable the language server for that file type in serena config","Check logs for language-server startup failures and fix them, then retry"],"exampleFix":"// before\nget_symbol_overview.apply(relative_path='README.md')\n// ValueError: Cannot extract symbols...\n\n// after\nif file.suffix in ('.py', '.ts', '.go', ...):  # LS-supported\n    get_symbol_overview.apply(relative_path=str(file))","handlingStrategy":"validation","validationCode":"supported_exts = {e for ls in agent.get_active_language_server_ids()\n                  for e in EXTENSIONS_FOR[ls]}  # e.g. py, ts, go...\nif Path(relative_path).suffix not in supported_exts:\n    raise SkipToolCall(f'{relative_path} not analyzable')","typeGuard":"def analyzable(rel: str) -> bool:\n    return Path(rel).suffix in SUPPORTED_SUFFIXES  # from active LS config","tryCatchPattern":"try:\n    overview = symbol_tool.get_symbol_overview(relative_path=rel)\nexcept ValueError as e:\n    if 'Cannot extract symbols' in str(e):\n        overview = text_based_fallback(rel)  # grep/AST without LS\n    else:\n        raise","preventionTips":["Only point symbol tools at source files of languages with active language servers","Verify language server startup in logs before using symbol tools","Keep config/data files (json, md, yaml) out of symbol queries"],"tags":["python","language-server","symbols","unsupported-file"],"backgroundTag":"unsupported-file-type","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}