oraios/serena · error · FileNotFoundError

phpantom_lsp executable not found at {binary_path}

Error message

phpantom_lsp executable not found at {binary_path}

What it means

After resolving (and, if missing, downloading) the pinned phpantom_lsp archive, the dependency provider re-checks that the binary actually exists at the expected binary_path. If the executable is still absent — the download/extraction did not produce the expected binary — this FileNotFoundError is raised. It is a post-install integrity check that the archive contained the binary named by the RuntimeDependency.

Source

Thrown at src/solidlsp/language_servers/phpantom.py:155

            system_phpantom = shutil.which("phpantom_lsp")
            if system_phpantom is not None:
                log.info(f"Using system-installed phpantom_lsp at {system_phpantom}")
                return system_phpantom

            # resolving the bundled binary
            phpantom_version = self._custom_settings.get("phpantom_version", DEFAULT_PHPANTOM_VERSION)
            dependencies = _create_phpantom_dependencies(phpantom_version)
            binary_dirname = "phpantom-lsp" if phpantom_version == INITIAL_PHPANTOM_VERSION else f"phpantom-lsp-{phpantom_version}"
            binary_dir = os.path.join(self._ls_resources_dir, binary_dirname)
            binary_path = dependencies.binary_path(binary_dir)
            if not os.path.exists(binary_path):
                os.makedirs(binary_dir, exist_ok=True)
                dep = dependencies.get_single_dep_for_current_platform("phpantom_lsp")
                log.info(f"Downloading phpantom_lsp from {dep.url}")
                dependencies.install(binary_dir)

            if not os.path.exists(binary_path):
                raise FileNotFoundError(f"phpantom_lsp executable not found at {binary_path}")

            if PlatformUtils.get_platform_id() not in (PlatformId.WIN_x64, PlatformId.WIN_arm64):
                current_mode = os.stat(binary_path).st_mode
                os.chmod(binary_path, current_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)

            return binary_path

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

    def __init__(self, config: LanguageServerConfig, repository_root_path: str, solidlsp_settings: SolidLSPSettings):
        super().__init__(config, repository_root_path, None, "php", solidlsp_settings)
        self._ignored_dirnames = {"node_modules", "cache"}
        if self._custom_settings.get("ignore_vendor", True):
            self._ignored_dirnames.add("vendor")
        log.info(f"Ignoring the following directories for PHP (PHPantom): {', '.join(sorted(self._ignored_dirnames))}")

    def _create_dependency_provider(self) -> LanguageServerDependencyProvider:

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Delete the cached install directory (…/ls_resources/phpantom-lsp-0.8.0 or phpantom-lsp) and let Serena re-download.
  2. Check logs just above the error for the download URL and any extraction/network errors during dependencies.install.
  3. Verify network access to github.com and release-assets.githubusercontent.com (corporate proxies commonly block these).
  4. Install phpantom_lsp manually and make it available on PATH so the bundled install path is skipped.
  5. Check free disk space and that the resources directory is writable.

Example fix

rm -rf ~/.cache/serena/language_servers/static/phpantom-lsp-0.8.0   # then re-run; forces a clean download
Defensive patterns

Strategy: try-catch

Validate before calling

import shutil
if shutil.which('phpantom_lsp') is None:
    # bundled path will download; ensure resources dir is writable and GitHub reachable
    import urllib.request
    urllib.request.urlopen('https://github.com/PHPantom-dev/phpantom_lsp/releases', timeout=10)

Try / catch

try:
    server = SolidLanguageServer.create('php', repo_root, settings)
except FileNotFoundError as e:
    if 'phpantom_lsp executable not found' in str(e):
        shutil.rmtree(Path(settings['ls_resources_dir']) / 'phpantom-lsp-0.8.0', ignore_errors=True)
        server = SolidLanguageServer.create('php', repo_root, settings)  # clean re-download
    else:
        raise

Prevention

When it happens

Trigger: Calling SolidLanguageServer.create for PHP without phpantom_lsp on PATH, where dependencies.install() ran but the binary did not appear at binary_path — e.g. the archive layout changed, the download was interrupted but a partial dir was cached, the disk was full, or a previous failed install left binary_dir without the executable so the 'if not os.path.exists' re-download was skipped.

Common situations: Corrupt or partial earlier download cached in the ls resources dir; platform mismatch where get_single_dep_for_current_platform found no matching dep so nothing was installed; proxy/network failure during dependencies.install; extraction skipped because a stale binary_dir already existed.

Related errors


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