oraios/serena · error · FileNotFoundError

ls_specific_settings.java.runtimes entry '{entry['name']}' p

Error message

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.

What it means

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.

Source

Thrown at src/solidlsp/language_servers/eclipse_jdtls.py:887

                f"got {type(configured_runtimes).__name__}: {configured_runtimes!r}"
            )

        # validate each entry and normalize it to the shape JDT-LS expects...
        validated_runtimes: list[dict[str, Any]] = []
        for entry in configured_runtimes:
            if not isinstance(entry, dict) or "name" not in entry or "path" not in entry:
                raise ValueError(
                    f"Invalid ls_specific_settings.java.runtimes entry {entry!r}: each entry requires at least a 'name' and a 'path' key."
                )
            path = entry["path"]
            if not os.path.exists(path):
                error_msg = (
                    f"ls_specific_settings.java.runtimes entry '{entry['name']}' points to a path that "
                    f"does not exist: {path}. Fix: update the path in ~/.serena/serena_config.yml "
                    f"(ls_specific_settings -> java -> runtimes), or remove the entry."
                )
                log.error(error_msg)
                raise FileNotFoundError(error_msg)

            runtime: dict[str, Any] = {"name": entry["name"], "path": path}
            if "default" in entry:
                runtime["default"] = bool(entry["default"])
            for optional_key in ("sources", "javadoc"):
                if optional_key in entry:
                    runtime[optional_key] = entry[optional_key]
            validated_runtimes.append(runtime)
            log.info(f"Registering additional JDT-LS runtime '{runtime['name']}' from custom settings: {path}")

        return validated_runtimes

    def _create_base_initialize_params(self) -> dict:
        """
        Returns the initialize parameters for the EclipseJDTLS server.
        """
        # 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

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Open ~/.serena/serena_config.yml, find ls_specific_settings -> java -> runtimes, and update the entry's path to an existing JDK home
  2. Or remove the stale entry from the runtimes list so Serena falls back to runtime discovery
  3. Verify with: ls <path>/bin/java (the path must point to a JDK home, not the java binary)
  4. If using SDKMAN/Homebrew, re-link or reinstall the JDK at the expected location

Example fix

# before (serena_config.yml)
runtimes:
  - name: "17"
    path: /usr/lib/jvm/jdk-17.0.2   # removed by system upgrade
// after
runtimes:
  - name: "17"
    path: /usr/lib/jvm/jdk-17.0.9   # existing JDK home
Defensive patterns

Strategy: validation

Validate before calling

import os, yaml
cfg = yaml.safe_load(open(os.path.expanduser('~/.serena/serena_config.yml')))
for rt in (cfg.get('ls_specific_settings', {}).get('java', {}).get('runtimes') or []):
    if not os.path.isdir(rt.get('path', '')):
        print(f"invalid runtime path for {rt.get('name')}: {rt.get('path')}")

Type guard

def runtime_entry_ok(entry: dict) -> bool:
    import os
    return isinstance(entry.get('path'), str) and os.path.isdir(entry['path'])

Try / catch

try:
    server = LanguageServer.create(LanguageServerId.JAVA, ...)
except FileNotFoundError as e:
    logger.error("Fix java runtimes in ~/.serena/serena_config.yml: %s", e)
    # fall back or abort with a clear user message

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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