{"record":{"id":"4c23f2d354376dbd","repo":"oraios/serena","slug":"opam-not-found-please-install-opam-https-opa","errorCode":null,"errorMessage":"opam not found. Please install opam:\n  https://opam.ocaml.org/doc/Install.html","messagePattern":"opam not found\\. Please install opam:\n  https://opam\\.ocaml\\.org/doc/Install\\.html","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/ocaml_lsp_server.py","lineNumber":141,"sourceCode":"            version_match = re.search(r\"(\\d+)\\.(\\d+)\\.(\\d+)\", version_str)\n            if version_match:\n                major = int(version_match.group(1))\n                minor = int(version_match.group(2))\n                patch = int(version_match.group(3))\n                version_tuple = (major, minor, patch)\n                log.info(f\"ocaml-lsp-server version: {major}.{minor}.{patch}\")\n                return version_tuple\n            raise RuntimeError(\n                f\"Could not parse ocaml-lsp-server version from output: {version_str}\\n\"\n                \"Please ensure ocaml-lsp-server is properly installed:\\n\"\n                \"  opam list -i ocaml-lsp-server\"\n            )\n        except subprocess.CalledProcessError as e:\n            raise RuntimeError(\n                f\"Failed to detect ocaml-lsp-server version: {e.stderr}\\nPlease install ocaml-lsp-server:\\n  opam install ocaml-lsp-server\"\n            ) from e\n        except FileNotFoundError as e:\n            raise RuntimeError(\"opam not found. Please install opam:\\n  https://opam.ocaml.org/doc/Install.html\") from e\n\n    @staticmethod\n    def _ensure_ocaml_lsp_installed(repository_root_path: str) -> str:\n        \"\"\"\n        Ensure ocaml-lsp-server is installed and return the executable path.\n        Raises RuntimeError with helpful message if not installed.\n        \"\"\"\n        # Check if ocaml-lsp-server is installed\n        try:\n            result = subprocess_run(\n                [\"opam\", \"list\", \"-i\", \"ocaml-lsp-server\"],\n                check=False,\n                capture_output=True,\n                text=True,\n                cwd=repository_root_path,\n                **subprocess_kwargs(),\n            )\n            if \"ocaml-lsp-server\" not in result.stdout or \"# No matches found\" in result.stdout:","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/ocaml_lsp_server.py#L123-L159","documentation":"This RuntimeError is raised when the opam executable itself is not found (FileNotFoundError) while trying to detect the ocaml-lsp-server version in _detect_lsp_version. It mirrors error 282 but originates from the version-detection path rather than the initial opam presence check, and simply directs the user to the opam installation docs.","triggerScenarios":"Constructing the OCaml language server on a machine where 'opam' is not on PATH of the running process, and the failure surfaces from _detect_lsp_version's subprocess call rather than _ensure_opam_installed (e.g. PATH changed or opam removed between checks, or the check path not exercised).","commonSituations":"IDE/extension hosts launching the library with a sanitized PATH lacking opam's install directory; opam uninstalled mid-session; containers where opam is only available in a user's login shell profile that isn't sourced.","solutions":["Install opam following https://opam.ocaml.org/doc/Install.html for your platform.","Ensure the opam bin directory is on PATH for the exact process running the code (export PATH=\"$HOME/.opam/default/bin:$PATH\" or eval $(opam env)).","Verify with 'which opam' in the same environment (IDE-spawned shells may differ).","Initialize after install: opam init, then create/activate a switch before starting the server."],"exampleFix":"// before: launching from IDE with minimal env\nspawn(process, { env: { PATH: \"/usr/bin:/bin\" } })\n// after\nspawn(process, { env: { PATH: process.env.PATH + \":\" + os.homedir() + \"/.opam/default/bin\" } })","handlingStrategy":"validation","validationCode":"import shutil, os\n\ndef require_opam_on_path() -> str:\n    opam = shutil.which(\"opam\")\n    if opam is None:\n        candidates = os.path.expanduser(\"~/.opam/default/bin\")\n        raise RuntimeError(\n            f\"opam not found on PATH (checked {os.environ.get('PATH','')!r}). \"\n            f\"Install opam and ensure {candidates} is exported in the launching environment.\"\n        )\n    return opam","typeGuard":null,"tryCatchPattern":"try:\n    server = OcamlLanguageServer(**kwargs)\nexcept RuntimeError as e:\n    if \"opam not found\" in str(e):\n        raise EnvironmentError(\n            \"opam binary unavailable to this process. Install it and add its bin dir \"\n            \"to the PATH of the exact process starting the server.\"\n        ) from e\n    raise","preventionTips":["Check 'which opam' from within the same launcher (IDE/CI runner) that will start the server, not only your terminal.","Export PATH additions in the process environment, not just shell dotfiles skipped by non-login shells.","After installing opam, run 'opam init' and 'eval $(opam env)' before first use.","Add a preflight binary check (shutil.which) to your app's startup diagnostics."],"tags":["ocaml","opam","missing-binary","environment","path"],"backgroundTag":"missing-binary","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}