oraios/serena · error · RuntimeError

Failed to detect OCaml version: {e.stderr} Please ensure OCa

Error message

Failed to detect OCaml version: {e.stderr}
Please ensure OCaml is installed and opam is configured:
  opam switch show
  opam exec -- ocaml -version

What it means

This RuntimeError is raised when the subprocess call used to detect the OCaml version exits with a non-zero status (subprocess.CalledProcessError). _detect_ocaml_version converts it into an actionable message including the subprocess stderr. It indicates opam is present but the version probe ('opam exec -- ocaml -version') failed.

Source

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

                patch = int(version_match.group(3))
                version_tuple = (major, minor, patch)
                version_str = f"{major}.{minor}.{patch}"
                log.info(f"OCaml version: {version_str}")

                if version_tuple == (5, 1, 0):
                    raise RuntimeError(
                        f"OCaml {version_str} is incompatible with ocaml-lsp-server.\n"
                        "Please use OCaml < 5.1 or >= 5.1.1.\n"
                        "Consider creating a new opam switch:\n"
                        "  opam switch create <name> ocaml-base-compiler.4.14.2"
                    )
                return version_tuple
            raise RuntimeError(
                f"Could not parse OCaml version from output: {result.stdout.strip()}\n"
                "Please ensure OCaml is properly installed: opam exec -- ocaml -version"
            )
        except subprocess.CalledProcessError as e:
            raise RuntimeError(
                f"Failed to detect OCaml version: {e.stderr}\n"
                "Please ensure OCaml is installed and opam is configured:\n"
                "  opam switch show\n"
                "  opam exec -- ocaml -version"
            ) from e
        except FileNotFoundError as e:
            raise RuntimeError(
                "OCaml not found. Please install OCaml via opam:\n"
                "  opam switch create <name> ocaml-base-compiler.4.14.2\n"
                "  eval $(opam env)"
            ) from e

    @staticmethod
    def _detect_lsp_version(repository_root_path: str) -> tuple[int, int, int]:
        """
        Detect and return the ocaml-lsp-server version as a tuple (major, minor, patch).
        Raises RuntimeError if version cannot be determined.
        """

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Run 'opam init' (or 'opam switch create <name> ocaml-base-compiler.4.14.2') if no switch exists.
  2. Activate a valid switch with 'opam switch <name>' then 'eval $(opam env)'.
  3. Check stderr in the error message for the concrete opam failure and fix that underlying issue.
  4. Verify the probe works: 'opam exec -- ocaml -version' should succeed before starting the server.

Example fix

// before (CI)
- opam install ocaml-lsp-server   # fails: no switch
// after
- opam init -y
- opam switch create default ocaml-base-compiler.5.1.1
- opam install -y ocaml-lsp-server
- eval $(opam env)
Defensive patterns

Strategy: validation

Validate before calling

import subprocess

def check_opam_switch_ready() -> None:
    subprocess.run(["opam", "switch", "show"], check=True, capture_output=True)
    subprocess.run(
        ["opam", "exec", "--", "ocaml", "-version"],
        check=True, capture_output=True,
    )  # non-zero exit here means an uninitialized/broken switch

Try / catch

try:
    server = OcamlLanguageServer(**kwargs)
except RuntimeError as e:
    if "Failed to detect OCaml version" in str(e):
        logger.error("opam probe failed: %s. Run 'opam init' / 'opam switch create' and 'eval $(opam env)', then retry.", e)
        raise
    raise

Prevention

When it happens

Trigger: Constructing the OCaml language server when 'opam exec -- ocaml -version' returns a non-zero exit code, e.g. no opam switch initialized/selected, broken switch, or ocaml not installed inside the current switch.

Common situations: opam installed but never 'opam init'-ed; empty opam root with no switches; switch exists but the compiler package was removed or the switch is corrupted; OPAMROOT pointing to a stale/incomplete directory in CI.

Related errors


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