oraios/serena · error · RuntimeError

ocaml-lsp-server executable not found at {executable_path}

Error message

ocaml-lsp-server executable not found at {executable_path}

What it means

Raised after the library resolves the ocamllsp executable path via opam (`opam var`/`opam exec -- where`) but `os.path.exists(executable_path)` is False. The check step succeeded yet the binary file is absent at the reported location, so the language server cannot be launched.

Source

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

                    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,
                    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)"
            )

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Run `eval $(opam env) && which ocamllsp` to see where the binary actually resolves and whether it exists.
  2. Reinstall the package: `opam reinstall ocaml-lsp-server` to recreate missing binaries.
  3. Verify the active switch is intact: `opam switch show`, `opam switch repair` if corrupted.
  4. Check that stdout of the lookup command isn't empty (empty path means opam can't locate ocamllsp — reinstall the package).

Example fix

// before (shell)
opam switch myswitch  # switch broken, binary missing
// after
opam switch repair && eval $(opam env) && opam reinstall ocaml-lsp-server
which ocamllsp  # verify path exists before starting server
Defensive patterns

Strategy: validation

Validate before calling

import subprocess, os
def ocamllsp_binary_present():
    r = subprocess.run(["opam", "exec", "--", "where", "ocamllsp"], capture_output=True, text=True)
    path = r.stdout.strip()
    return bool(path) and os.path.exists(path)

Prevention

When it happens

Trigger: Instantiating OcamlLSPServer when `opam exec -- where ocamllsp` (Windows) or the Unix lookup returns a path that does not exist — e.g. empty stdout stripped to '', a stale opam switch, or a package installed but binary removed.

Common situations: Empty or stale switch after `opam update`/switch removal; `where` returning an empty string on misconfigured opam; package registered but files pruned; symlink to a removed target; Windows path resolution returning a nonexistent location.

Related errors


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