{"record":{"id":"0ac917f7db4400c1","repo":"oraios/serena","slug":"language-server-for-language-ls-id-value-already","errorCode":null,"errorMessage":"Language server for language {ls_id.value} already present","messagePattern":"Language server for language (.+?) already present","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/serena/ls_manager.py","lineNumber":211,"sourceCode":"        Forces recreation and restart of the language server for the given language.\n        It is assumed that the language server for the given language is no longer running.\n\n        :param language: the language\n        :return: the newly created language server\n        \"\"\"\n        if language not in self._language_servers:\n            raise ValueError(f\"No language server for language {language.value} present; cannot restart\")\n        return self._create_and_start_language_server(language)\n\n    def add_language_server(self, ls_id: LanguageServerId) -> SolidLanguageServer:\n        \"\"\"\n        Dynamically adds a new language server for the given language.\n\n        :param ls_id: the language server to add\n        :return: the newly created language server\n        \"\"\"\n        if ls_id in self._language_servers:\n            raise ValueError(f\"Language server for language {ls_id.value} already present\")\n        return self._create_and_start_language_server(ls_id)\n\n    def remove_language_server(self, language: LanguageServerId, save_cache: bool = False) -> None:\n        \"\"\"\n        Removes the language server for the given language, stopping it if it is running.\n\n        :param language: the language\n        \"\"\"\n        if language not in self._language_servers:\n            raise ValueError(f\"No language server for language {language.value} present; cannot remove\")\n        ls = self._language_servers.pop(language)\n        self._stop_language_server(ls, save_cache=save_cache)\n\n    def get_active_language_server_ids(self) -> list[LanguageServerId]:\n        \"\"\"\n        Returns the list of languages for which language servers are currently managed.\n\n        :return: list of languages","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/serena/ls_manager.py#L193-L229","documentation":"add_language_server refuses duplicates: if a server for the requested language is already managed, it raises ValueError rather than replacing it. To replace a server, remove_language_server must be called first.","triggerScenarios":"Calling add_language_server(ls_id) twice; calling add for a language already started by from_languages; _ensure_functional_ls recovery logic racing with a user-initiated add.","commonSituations":"Startup code unconditionally adds servers after from_languages already created them; retry logic re-adding after a partial failure where the server actually started; plugin enabling a language that's already enabled.","solutions":["Check ls_id in get_active_language_server_ids() before adding","If replacement is intended, call remove_language_server(ls_id) first, then add_language_server","Reuse the existing server via get_language_server for a representative file","Wrap in try/except ValueError and treat 'already present' as success"],"exampleFix":"// before\nmanager.add_language_server(LanguageServerId.PYTHON)\n# second call raises ValueError\nmanager.add_language_server(LanguageServerId.PYTHON)\n// after\nif LanguageServerId.PYTHON not in manager.get_active_language_server_ids():\n    manager.add_language_server(LanguageServerId.PYTHON)","handlingStrategy":"validation","validationCode":"if ls_id in manager.get_active_language_server_ids():\n    manager.remove_language_server(ls_id)\nmanager.add_language_server(ls_id)","typeGuard":null,"tryCatchPattern":"try:\n    manager.add_language_server(ls_id)\nexcept ValueError as e:\n    if \"already present\" in str(e):\n        pass  # treat as success\n    else:\n        raise","preventionTips":["Check active ids before adding","Only call add_language_server for genuinely new languages","For replacement, remove first then add","Make idempotent startup code that tolerates 'already present'"],"tags":["language-server","duplicate","state-management"],"backgroundTag":"duplicate-resource-conflict","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}