oraios/serena · error · ValueError

No language server factory available to create language serv

Error message

No language server factory available to create language server for {ls_id}

What it means

_create_and_start_language_server requires the optional _language_server_factory to create servers on demand. A manager built without a factory (e.g. the default constructor path where factory is None) cannot create new servers, so it raises ValueError naming the requested language.

Source

Thrown at src/serena/ls_manager.py:185

        for candidate in self._language_servers.values():
            if not candidate.is_ignored_path(relative_path, ignore_unsupported_files=True):
                return candidate
        return None

    def get_language_server(self, relative_path: str) -> SolidLanguageServer:
        """:param relative_path: relative path to a file"""
        ls: SolidLanguageServer | None = None
        if len(self._language_servers) > 1:
            if os.path.isdir(relative_path):
                raise ValueError(f"Expected a file path, but got a directory: {relative_path}")
            ls = self._get_suitable_language_server(relative_path)
        if ls is None:
            ls = self._default_language_server
        return self._ensure_functional_ls(ls)

    def _create_and_start_language_server(self, ls_id: LanguageServerId) -> SolidLanguageServer:
        if self._language_server_factory is None:
            raise ValueError(f"No language server factory available to create language server for {ls_id}")
        language_server = self._language_server_factory.create_language_server(ls_id)
        language_server.start()
        self._language_servers[ls_id] = language_server
        return language_server

    def restart_language_server(self, language: LanguageServerId) -> SolidLanguageServer:
        """
        Forces recreation and restart of the language server for the given language.
        It is assumed that the language server for the given language is no longer running.

        :param language: the language
        :return: the newly created language server
        """
        if language not in self._language_servers:
            raise ValueError(f"No language server for language {language.value} present; cannot restart")
        return self._create_and_start_language_server(language)

    def add_language_server(self, ls_id: LanguageServerId) -> SolidLanguageServer:

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Construct the manager via from_languages so a factory is always present
  2. Pass the LanguageServerFactory explicitly when constructing LanguageServerManager
  3. Recreate the manager with a factory instead of calling add/restart on a factory-less instance

Example fix

// before
manager = LanguageServerManager({}, None, project)
manager.add_language_server(LanguageServerId.PYTHON)  # ValueError
// after
manager = LanguageServerManager({}, my_factory, project)
manager.add_language_server(LanguageServerId.PYTHON)
Defensive patterns

Strategy: validation

Validate before calling

if not manager.get_active_language_server_ids() and manager_is_factoryless:
    raise RuntimeError("manager has no factory; recreate via from_languages")

Try / catch

try:
    ls = manager.add_language_server(ls_id)
except ValueError as e:
    if "No language server factory available" in str(e):
        manager = LanguageServerManager.from_languages([ls_id], factory, project)
        ls = manager.get_language_server(representative_file)
    else:
        raise

Prevention

When it happens

Trigger: Calling restart_language_server or add_language_server on a manager whose _language_server_factory is None — typically a manager constructed directly rather than via from_languages, or deserialized/pickled where the factory was dropped.

Common situations: Manually constructed LanguageServerManager with factory=None; manager obtained through a path that doesn't wire the factory; dynamic language addition attempted on a read-only/prebuilt manager.

Related errors


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