oraios/serena · error · FileNotFoundError

typescript-language-server executable not found at

Error message

typescript-language-server executable not found at {tsserver_executable_path}, something went wrong with the installation.

What it means

Thrown as FileNotFoundError when, after running the dependency installer for the typescript-language-server npm package, the expected tsserver executable still does not exist on disk at tsserver_executable_path. It indicates the automated installation step completed without producing the binary the server launch needs.

Solutions

  1. Delete the typescript language server install directory and retry, letting deps.install run fresh.
  2. Run the npm install manually (npm install -g typescript typescript-language-server) and check npm/network errors.
  3. Verify network/proxy/registry settings (npm config get registry; corporate proxy env vars).
  4. Check disk space and directory write permissions for the install location.
  5. If a global install exists, configure ls_path/ls_specific_settings to point at it and bypass auto-install.

Example fix

// before: relying on auto-install that fails behind a proxy
ls = SolidLSP("ts", "/repo")
// after: pre-install and point the server at the binary
// $ npm install -g typescript typescript-language-server
settings = {"ls_specific_settings": {"typescript": {"ls_path": "/usr/local/bin/typescript-language-server"}}}
ls = SolidLSP("ts", "/repo", settings)
Defensive patterns

Strategy: try-catch

Validate before calling

import os, shutil
if not (os.path.exists(expected_tsserver_path) or shutil.which("typescript-language-server")):
    # pre-install before constructing the server
    subprocess.run(["npm", "install", "-g", "typescript", "typescript-language-server"], check=True)

Type guard

def has_ts_ls(path: str) -> bool:
    return os.path.isfile(path) and os.access(path, os.X_OK)

Try / catch

try:
    ls = SolidLSP("typescript", repo_path)
except FileNotFoundError as e:
    if "typescript-language-server executable not found" in str(e):
        subprocess.run(["npm", "install", "-g", "typescript", "typescript-language-server"], check=True)
        ls = SolidLSP("typescript", repo_path)
    else:
        raise

Prevention

When it happens

Trigger: Calling SolidLSP for TypeScript triggers _get_or_install_core_dependency; deps.install(tsserver_ls_dir) runs but the tsserver executable is still absent when re-checked with os.path.exists.

Common situations: npm install silently failing behind a corporate proxy or with bad registry config; disk full; installing into a directory without write/execute permissions; partial installs left over from an interrupted run; native binary download blocked by antivirus.

Related errors


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

Appendix: source

Thrown at src/solidlsp/language_servers/typescript_language_server.py:332

            assert is_npm_installed, "npm is not installed or isn't in PATH. Please install npm and try again."

            # legacy unversioned dir reserved for INITIAL pair; any other version combination goes into a versioned subdir
            is_initial = (
                typescript_version == INITIAL_TYPESCRIPT_VERSION
                and typescript_language_server_version == INITIAL_TYPESCRIPT_LANGUAGE_SERVER_VERSION
            )
            ls_dirname = "ts-lsp" if is_initial else f"ts-lsp-{typescript_version}-{typescript_language_server_version}"
            tsserver_ls_dir = os.path.join(self._ls_resources_dir, ls_dirname)
            tsserver_executable_path = os.path.join(tsserver_ls_dir, "node_modules", ".bin", "typescript-language-server")

            if not os.path.exists(tsserver_executable_path):
                log.info(f"Typescript Language Server executable not found at {tsserver_executable_path}. Installing...")
                with LogTime("Installation of TypeScript language server dependencies", logger=log):
                    deps.install(tsserver_ls_dir)
                log.info("TypeScript language server dependencies installed successfully")

            if not os.path.exists(tsserver_executable_path):
                raise FileNotFoundError(
                    f"typescript-language-server executable not found at {tsserver_executable_path}, something went wrong with the installation."
                )
            return tsserver_executable_path

        def _create_launch_command(self, core_path: str) -> list[str]:
            return [core_path, "--stdio"]

    def _get_language_id_for_file(self, relative_file_path: str) -> str:
        # JSX is parsed as TS without this, which silently truncates symbol
        # ranges at the first multi-line JSX expression.
        if relative_file_path.endswith(".tsx"):
            return "typescriptreact"
        if relative_file_path.endswith(".jsx"):
            return "javascriptreact"
        return self.language_id

    def _create_base_initialize_params(self) -> dict:
        initialize_params = {

View on GitHub (pinned to 7fcbca7e62)