oraios/serena · error · ValueError

ls_specific_settings.java.runtimes must be a list of {name,

Error message

ls_specific_settings.java.runtimes must be a list of {name, path} entries, got {type(configured_runtimes).__name__}: {configured_runtimes!r}

What it means

ValueError raised by _resolve_configured_runtimes when ls_specific_settings.java.runtimes is set but is not a list. The setting is expected to be a list of {name, path} JDK runtime entries that get validated and normalized into the javaRuntimes structure JDT-LS understands.

Source

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

        # bundled runtime fallback...
        log.info(f"Using bundled JRE for Gradle: {self.runtime_dependency_paths.jre_path}")
        return self.runtime_dependency_paths.jre_path

    def _resolve_configured_runtimes(self) -> list[dict[str, Any]]:
        """
        Validate and normalize the optional extra JRE/JDK runtimes to register with JDT-LS, as configured
        via ``ls_specific_settings.java.runtimes``. Each entry mirrors the shape VS Code's Java extension
        sends via ``java.configuration.runtimes`` (``name``, ``path``, optional ``default``/``sources``/
        ``javadoc``); see serena #1478.

        :return: the validated list of runtime dicts (empty if the setting is unset)
        :raises ValueError: if the setting or one of its entries is malformed
        :raises FileNotFoundError: if an entry's ``path`` does not exist
        """
        configured_runtimes = self._custom_settings.get("runtimes", [])
        if not isinstance(configured_runtimes, list):
            raise ValueError(
                f"ls_specific_settings.java.runtimes must be a list of {{name, path}} entries, "
                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."
                )

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Make runtimes a YAML/JSON list of entries, each with at least 'name' and 'path'
  2. Wrap a single runtime object in a list: runtimes: [{name: ..., path: ...}]
  3. Fix indentation so entries are list items (leading '-'), not mapping keys

Example fix

# before
ls_specific_settings:
  java:
    runtimes:
      name: JavaSE-21
      path: /usr/lib/jvm/temurin-21
# after
ls_specific_settings:
  java:
    runtimes:
      - name: JavaSE-21
        path: /usr/lib/jvm/temurin-21
Defensive patterns

Strategy: type-guard

Validate before calling

import yaml
cfg = yaml.safe_load(open("~/.serena/serena_config.yml"))
runtimes = cfg.get("ls_specific_settings", {}).get("java", {}).get("runtimes", [])
assert isinstance(runtimes, list), "runtimes must be a list of {name, path} entries"

Type guard

def is_runtimes_list(v: object) -> bool:
    return isinstance(v, list)

Try / catch

try:
    params = provider._create_base_initialize_params()
except ValueError as e:
    if str(e).startswith("ls_specific_settings.java.runtimes must be a list"):
        cfg["ls_specific_settings"]["java"]["runtimes"] = [cfg["ls_specific_settings"]["java"]["runtimes"]]  # wrap single object in list
        params = provider._create_base_initialize_params()
    else:
        raise

Prevention

When it happens

Trigger: _create_base_initialize_params -> _resolve_configured_runtimes where custom_settings['runtimes'] is a dict, string, or other non-list type; the isinstance(configured_runtimes, list) check fails and raises immediately.

Common situations: YAML mapping used instead of a YAML list (indentation mistake); runtimes written as a single object instead of a one-element list; JSON config with braces instead of brackets.

Related errors


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