oraios/serena · error · RuntimeError

Failed to check ocaml-lsp-server installation: {e.stderr}

Error message

Failed to check ocaml-lsp-server installation: {e.stderr}

What it means

Raised when the `opam list` command used to verify ocaml-lsp-server installation exits with a non-zero status (subprocess.CalledProcessError), and the library wraps it in a RuntimeError including opam's stderr. Unlike [290], this means the installation CHECK itself failed, not that the package is missing.

Source

Thrown at src/solidlsp/language_servers/ocaml_lsp_server.py:174

                cwd=repository_root_path,
                **subprocess_kwargs(),
            )
            if "ocaml-lsp-server" not in result.stdout or "# No matches found" in result.stdout:
                raise RuntimeError(
                    "ocaml-lsp-server is not installed.\n\n"
                    "Please install it with:\n"
                    "  opam install ocaml-lsp-server\n\n"
                    "Note: ocaml-lsp-server requires OCaml < 5.1 or >= 5.1.1 (OCaml 5.1.0 is not supported).\n"
                    "If you have OCaml 5.1.0, create a new opam switch with a compatible version:\n"
                    "  opam switch create <name> ocaml-base-compiler.4.14.2\n"
                    "  opam switch <name>\n"
                    "  eval $(opam env)\n"
                    "  opam install ocaml-lsp-server\n\n"
                    "For more information: https://github.com/ocaml/ocaml-lsp"
                )
            log.info("ocaml-lsp-server is installed")
        except subprocess.CalledProcessError as e:
            raise RuntimeError(f"Failed to check ocaml-lsp-server installation: {e.stderr}")

        # Find the executable path
        try:
            if platform.system() == "Windows":
                result = subprocess_run(
                    ["opam", "exec", "--", "where", "ocamllsp"],
                    check=True,
                    capture_output=True,
                    text=True,
                    cwd=repository_root_path,
                    **subprocess_kwargs(),
                )
                executable_path = result.stdout.strip().split("\n")[0]
            else:
                result = subprocess_run(
                    ["opam", "exec", "--", "which", "ocamllsp"],
                    check=True,
                    capture_output=True,

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Run `opam list` manually in the repo root to see the actual opam error from stderr.
  2. If opam is uninitialized, run `opam init` then `eval $(opam env)`.
  3. Ensure the opam binary is on PATH for the process launching the server (env inheritance; in CI, source `~/.opam/opam-init/init.sh` or run `eval $(opam env)`).
  4. Repair a broken switch with `opam switch repair` or recreate it with `opam switch create`.

Example fix

// before (Python, env lacks opam)
subprocess.run(["opam", "list", ...])  # CalledProcessError: opam not found
// after
import os, subprocess
env = os.environ.copy()
# ensure opam env loaded, e.g. in shell: eval $(opam env)
subprocess.run(["opam", "list", ...], env=env, cwd=repository_root_path)
Defensive patterns

Strategy: try-catch

Validate before calling

import shutil, subprocess
def opam_ok(repo_root):
    if not shutil.which("opam"):
        return False
    return subprocess.run(["opam", "list"], capture_output=True, cwd=repo_root).returncode == 0

Try / catch

try:
    server = OcamlLSPServer(repo_root)
except RuntimeError as e:
    if "Failed to check ocaml-lsp-server installation" in str(e):
        run("opam init -y") ; run("eval $(opam env)")  # fix opam env, then retry
    else:
        raise

Prevention

When it happens

Trigger: Instantiating OcamlLSPServer when `opam list -- ... ocaml-lsp-server` returns non-zero — typically `opam: command not found`-style environment failures, a corrupted opam root, or opam errors about an uninitialized/invalid switch (opam itself may emit errors on stderr).

Common situations: opam not on PATH for the subprocess environment; opam root uninitialized (`opam init` never run); broken or corrupt switch (~/.opam damaged); restricted CI container with no opam config; HOME mismatch causing opam to fail.

Related errors


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