{"record":{"id":"846198e51db771e8","repo":"oraios/serena","slug":"ls-specific-settings-java-runtimes-entry-entry","errorCode":null,"errorMessage":"ls_specific_settings.java.runtimes entry '{entry['name']}' points to a path that does not exist: {path}. Fix: update the path in ~/.serena/serena_config.yml (ls_specific_settings -> java -> runtimes), or remove the entry.","messagePattern":"ls_specific_settings\\.java\\.runtimes entry '(.+?)' points to a path that does not exist: (.+?)\\. Fix: update the path in ~/\\.serena/serena_config\\.yml \\(ls_specific_settings -> java -> runtimes\\), or remove the entry\\.","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/eclipse_jdtls.py","lineNumber":887,"sourceCode":"                f\"got {type(configured_runtimes).__name__}: {configured_runtimes!r}\"\n            )\n\n        # validate each entry and normalize it to the shape JDT-LS expects...\n        validated_runtimes: list[dict[str, Any]] = []\n        for entry in configured_runtimes:\n            if not isinstance(entry, dict) or \"name\" not in entry or \"path\" not in entry:\n                raise ValueError(\n                    f\"Invalid ls_specific_settings.java.runtimes entry {entry!r}: each entry requires at least a 'name' and a 'path' key.\"\n                )\n            path = entry[\"path\"]\n            if not os.path.exists(path):\n                error_msg = (\n                    f\"ls_specific_settings.java.runtimes entry '{entry['name']}' points to a path that \"\n                    f\"does not exist: {path}. Fix: update the path in ~/.serena/serena_config.yml \"\n                    f\"(ls_specific_settings -> java -> runtimes), or remove the entry.\"\n                )\n                log.error(error_msg)\n                raise FileNotFoundError(error_msg)\n\n            runtime: dict[str, Any] = {\"name\": entry[\"name\"], \"path\": path}\n            if \"default\" in entry:\n                runtime[\"default\"] = bool(entry[\"default\"])\n            for optional_key in (\"sources\", \"javadoc\"):\n                if optional_key in entry:\n                    runtime[optional_key] = entry[optional_key]\n            validated_runtimes.append(runtime)\n            log.info(f\"Registering additional JDT-LS runtime '{runtime['name']}' from custom settings: {path}\")\n\n        return validated_runtimes\n\n    def _create_base_initialize_params(self) -> dict:\n        \"\"\"\n        Returns the initialize parameters for the EclipseJDTLS server.\n        \"\"\"\n        # Look into https://github.com/eclipse/eclipse.jdt.ls/blob/master/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/preferences/Preferences.java to understand all the options available\n","sourceCodeStart":869,"sourceCodeEnd":905,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/eclipse_jdtls.py#L869-L905","documentation":"Serena validates each Java runtime entry configured under ls_specific_settings.java.runtimes in ~/.serena/serena_config.yml during JDTLS initialization. If the entry's 'path' does not exist on disk, _resolve_configured_runtimes raises FileNotFoundError so the language server fails fast instead of later breaking code resolution. It names the offending entry and tells you which config key to fix.","triggerScenarios":"Calling _create_base_initialize_params (i.e., starting the Eclipse JDTLS language server) while a runtimes entry in ~/.serena/serena_config.yml has a 'path' that os.path.exists() cannot find — a deleted/renamed JDK directory, a typo, or a stale entry left after a JDK upgrade.","commonSituations":"Upgrading or uninstalling a JDK (e.g., removing a Homebrew/SDKMAN-managed JDK) leaving the old path in serena_config.yml; moving a JDK between machines; typos in the configured path; container/CI images where the configured JDK was never installed.","solutions":["Open ~/.serena/serena_config.yml, find ls_specific_settings -> java -> runtimes, and update the entry's path to an existing JDK home","Or remove the stale entry from the runtimes list so Serena falls back to runtime discovery","Verify with: ls <path>/bin/java (the path must point to a JDK home, not the java binary)","If using SDKMAN/Homebrew, re-link or reinstall the JDK at the expected location"],"exampleFix":"# before (serena_config.yml)\nruntimes:\n  - name: \"17\"\n    path: /usr/lib/jvm/jdk-17.0.2   # removed by system upgrade\n// after\nruntimes:\n  - name: \"17\"\n    path: /usr/lib/jvm/jdk-17.0.9   # existing JDK home\n","handlingStrategy":"validation","validationCode":"import os, yaml\ncfg = yaml.safe_load(open(os.path.expanduser('~/.serena/serena_config.yml')))\nfor rt in (cfg.get('ls_specific_settings', {}).get('java', {}).get('runtimes') or []):\n    if not os.path.isdir(rt.get('path', '')):\n        print(f\"invalid runtime path for {rt.get('name')}: {rt.get('path')}\")","typeGuard":"def runtime_entry_ok(entry: dict) -> bool:\n    import os\n    return isinstance(entry.get('path'), str) and os.path.isdir(entry['path'])","tryCatchPattern":"try:\n    server = LanguageServer.create(LanguageServerId.JAVA, ...)\nexcept FileNotFoundError as e:\n    logger.error(\"Fix java runtimes in ~/.serena/serena_config.yml: %s\", e)\n    # fall back or abort with a clear user message","preventionTips":["After any JDK upgrade/uninstall, re-check serena_config.yml runtimes paths","Use a JDK discovery helper (SDKMAN/Homebrew paths) to generate entries","Add serena_config.yml path checks to environment bootstrap scripts","Keep runtimes entries minimal; rely on auto-discovery when possible"],"tags":["java","file-not-found","configuration","jdtls"],"backgroundTag":"config-path-not-found","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}