{"record":{"id":"8ac8c1ac3b3842c9","repo":"oraios/serena","slug":"invalid-ls-specific-settings-java-runtimes-entry","errorCode":null,"errorMessage":"Invalid ls_specific_settings.java.runtimes entry {entry!r}: each entry requires at least a 'name' and a 'path' key.","messagePattern":"Invalid ls_specific_settings\\.java\\.runtimes entry (.+?): each entry requires at least a 'name' and a 'path' key\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/eclipse_jdtls.py","lineNumber":876,"sourceCode":"        sends via ``java.configuration.runtimes`` (``name``, ``path``, optional ``default``/``sources``/\n        ``javadoc``); see serena #1478.\n\n        :return: the validated list of runtime dicts (empty if the setting is unset)\n        :raises ValueError: if the setting or one of its entries is malformed\n        :raises FileNotFoundError: if an entry's ``path`` does not exist\n        \"\"\"\n        configured_runtimes = self._custom_settings.get(\"runtimes\", [])\n        if not isinstance(configured_runtimes, list):\n            raise ValueError(\n                f\"ls_specific_settings.java.runtimes must be a list of {{name, path}} entries, \"\n                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]","sourceCodeStart":858,"sourceCodeEnd":894,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/eclipse_jdtls.py#L858-L894","documentation":"ValueError raised by _resolve_configured_runtimes when an entry in ls_specific_settings.java.runtimes is not a dict or lacks the required 'name' and/or 'path' keys. Each entry must identify a named JDK (e.g. JavaSE-21) and its installation path so it can be normalized into JDT-LS's javaRuntimes format.","triggerScenarios":"_create_base_initialize_params -> _resolve_configured_runtimes iterating the runtimes list: an entry fails 'isinstance(entry, dict) and \"name\" in entry and \"path\" in entry', e.g. a bare string path, or a dict missing 'path'.","commonSituations":"List of plain path strings instead of dicts; typo'd key ('paht', 'jdk_name'); entry with only 'name' and the path given as a sibling key; copy-paste leaving an entry half-filled.","solutions":["Give each entry both 'name' and 'path' keys, e.g. {name: JavaSE-21, path: /usr/lib/jvm/temurin-21}","Convert bare string paths into dict entries","Fix typo'd key names so 'name' and 'path' exist exactly","Ensure the 'path' points to an existing JDK home (a follow-up FileNotFoundError otherwise)"],"exampleFix":"# before\nruntimes:\n  - /usr/lib/jvm/temurin-21\n# after\nruntimes:\n  - name: JavaSE-21\n    path: /usr/lib/jvm/temurin-21","handlingStrategy":"validation","validationCode":"from pathlib import Path\ndef validate_runtime_entries(runtimes: list) -> bool:\n    return all(\n        isinstance(r, dict) and \"name\" in r and \"path\" in r and Path(r[\"path\"]).exists()\n        for r in runtimes\n    )","typeGuard":"def is_valid_runtime_entry(e: object) -> bool:\n    return (\n        isinstance(e, dict)\n        and isinstance(e.get(\"name\"), str)\n        and isinstance(e.get(\"path\"), str)\n        and Path(e[\"path\"]).exists()\n    )","tryCatchPattern":"try:\n    params = provider._create_base_initialize_params()\nexcept ValueError as e:\n    if \"requires at least a 'name' and a 'path' key\" in str(e):\n        cfg[\"ls_specific_settings\"][\"java\"][\"runtimes\"] = fix_entries(cfg[\"ls_specific_settings\"][\"java\"][\"runtimes\"])\n        params = provider._create_base_initialize_params()\n    else:\n        raise","preventionTips":["Always model a runtime as {name: 'JavaSE-21', path: <jdk home>}, never a bare path string","Spell keys exactly 'name' and 'path'","Point 'path' at an existing JDK home to also avoid the follow-up FileNotFoundError","Copy runtime entries from working examples rather than hand-writing them"],"tags":["configuration","schema-validation","jdtls","yaml"],"backgroundTag":"invalid-config-entry","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}