oraios/serena · error · RuntimeError

Failed to find ocaml-lsp-server executable. Command failed:

Error message

Failed to find ocaml-lsp-server executable.
Command failed: {e.cmd}
Return code: {e.returncode}
Stderr: {e.stderr}

This usually means ocaml-lsp-server is not installed or not in PATH.
Try:
  1. Check opam switch: opam switch show
  2. Install ocaml-lsp-server: opam install ocaml-lsp-server

What it means

Raised when the subprocess command that locates the ocamllsp executable (e.g. `opam var lib` / `opam exec -- where ocamllsp`) exits non-zero (subprocess.CalledProcessError). The message includes the failed command, return code, and stderr, and points to likely causes: ocaml-lsp-server missing or not in PATH for the current switch.

Source

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

                    ["opam", "exec", "--", "which", "ocamllsp"],
                    check=True,
                    capture_output=True,
                    text=True,
                    cwd=repository_root_path,
                    **subprocess_kwargs(),
                )
                executable_path = result.stdout.strip()

            if not os.path.exists(executable_path):
                raise RuntimeError(f"ocaml-lsp-server executable not found at {executable_path}")

            if platform.system() != "Windows":
                os.chmod(executable_path, os.stat(executable_path).st_mode | stat.S_IEXEC)

            return executable_path

        except subprocess.CalledProcessError as e:
            raise RuntimeError(
                f"Failed to find ocaml-lsp-server executable.\n"
                f"Command failed: {e.cmd}\n"
                f"Return code: {e.returncode}\n"
                f"Stderr: {e.stderr}\n\n"
                "This usually means ocaml-lsp-server is not installed or not in PATH.\n"
                "Try:\n"
                "  1. Check opam switch: opam switch show\n"
                "  2. Install ocaml-lsp-server: opam install ocaml-lsp-server\n"
                "  3. Ensure opam env is activated: eval $(opam env)"
            )

    @property
    def supports_cross_file_references(self) -> bool:
        """
        Check if this OCaml environment supports cross-file references.

        Cross-file references require OCaml >= 5.2 with project-wide occurrences
        AND ocaml-lsp-server >= 1.23.0 for reliable cross-file reference support.

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Check the active switch: `opam switch show`; switch to the intended one: `opam switch <name> && eval $(opam env)`.
  2. Install the server: `opam install ocaml-lsp-server`, then verify with `which ocamllsp`.
  3. Load opam's environment before launching (`eval $(opam env)`) so the subprocess sees opam and its paths.
  4. If opam itself is broken, run the failed command manually and inspect stderr; repair with `opam switch repair` or `opam init`.
  5. Read the stderr in the error message — it names the exact command and failure.

Example fix

// before (shell, no opam env in launcher)
python -m app  # subprocess can't resolve ocamllsp
// after
eval $(opam env)
opam install ocaml-lsp-server
python -m app
Defensive patterns

Strategy: try-catch

Validate before calling

import shutil, subprocess
def can_locate_ocamllsp():
    return shutil.which("opam") is not None and subprocess.run(
        ["opam", "exec", "--", "where", "ocamllsp"], capture_output=True
    ).returncode == 0

Try / catch

try:
    server = OcamlLSPServer(repo_root)
except RuntimeError as e:
    if "Failed to find ocaml-lsp-server executable" in str(e):
        # e.stderr names the failing opam command; fix switch/env then retry
        run("eval $(opam env) && opam install ocaml-lsp-server -y")
        server = OcamlLSPServer(repo_root)
    else:
        raise

Prevention

When it happens

Trigger: Instantiating OcamlLSPServer when the executable-lookup subprocess fails — opam erroring out, wrong/uninitialized switch, or ocamllsp not installed in the active switch so the lookup command returns failure.

Common situations: Wrong opam switch selected (one without ocaml-lsp-server); opam env not loaded in the launching shell; CI runner without the package installed; opam failing due to a corrupted root.

Related errors


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