{"record":{"id":"ebdd2c02b2aa760a","repo":"oraios/serena","slug":"provided-jdtls-path-jdtls-path-is-not-an-exist","errorCode":null,"errorMessage":"Provided jdtls_path '{jdtls_path}' is not an existing directory.\nFix: extract jdt-language-server-*.tar.gz from https://download.eclipse.org/jdtls/snapshots/ or run 'brew install jdtls', then set ls_specific_settings.java.jdtls_path to the extracted directory.","messagePattern":"Provided jdtls_path '(.+?)' is not an existing directory\\.\nFix: extract jdt-language-server-\\*\\.tar\\.gz from https://download\\.eclipse\\.org/jdtls/snapshots/ or run 'brew install jdtls', then set ls_specific_settings\\.java\\.jdtls_path to the extracted directory\\.","errorType":"exception","errorClass":"SolidLSPException","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/eclipse_jdtls.py","lineNumber":475,"sourceCode":"            )\n\n        @staticmethod\n        def _setup_from_existing_install(\n            jdtls_path: str, lombok_path: str, custom_settings: SolidLSPSettings.CustomLSSettings\n        ) -> RuntimeDependencyPaths:\n            \"\"\"\n            Builds RuntimeDependencyPaths from an already-installed upstream JDTLS distribution\n            and the system-installed JDK. No downloads are performed.\n\n            :param jdtls_path: absolute path to the JDTLS root (containing ``plugins/`` and ``config_<platform>/``)\n            :param lombok_path: absolute path to the Lombok jar (mandatory; agent is always attached)\n            :param custom_settings: language-server-specific settings from ls_specific_settings.java\n            :return: populated RuntimeDependencyPaths with ``gradle_path`` set to ``None``\n            \"\"\"\n            # validate jdtls_path structure (root + plugins dir)\n            jdtls_root = Path(jdtls_path)\n            if not jdtls_root.is_dir():\n                raise SolidLSPException(\n                    f\"Provided jdtls_path '{jdtls_path}' is not an existing directory.\\n\"\n                    f\"Fix: extract jdt-language-server-*.tar.gz from \"\n                    f\"https://download.eclipse.org/jdtls/snapshots/ or run 'brew install jdtls', \"\n                    f\"then set ls_specific_settings.java.jdtls_path to the extracted directory.\"\n                )\n            plugins_dir = jdtls_root / \"plugins\"\n            if not plugins_dir.is_dir():\n                raise SolidLSPException(\n                    f\"Invalid jdtls_path '{jdtls_path}': 'plugins/' directory not found.\\n\"\n                    f\"Expected upstream JDTLS layout (plugins/, config_<platform>/, features/) at the root. \"\n                    f\"If you pointed at a vscode-java extension, use '<extension>/server' instead.\"\n                )\n\n            # resolve the main equinox launcher jar (excluding platform-specific native fragments)\n            launcher_jar = EclipseJDTLS.DependencyProvider._resolve_launcher_jar(plugins_dir)\n\n            # resolve the platform-specific config directory under jdtls_root\n            config_dir = EclipseJDTLS.DependencyProvider._resolve_config_dir(jdtls_root)","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/eclipse_jdtls.py#L457-L493","documentation":"This SolidLSPException is raised in _setup_from_existing_install when the configured jdtls_path does not exist as a directory on disk. Upstream JDTLS mode expects the user to have extracted the official jdt-language-server tarball (or installed via brew) and pointed jdtls_path at the extracted root.","triggerScenarios":"Starting EclipseJDTLS in upstream mode where Path(jdtls_path).is_dir() is False: path never existed, tarball was never extracted, wrong directory given, or relative path resolved differently than expected.","commonSituations":"User set jdtls_path to the .tar.gz file itself instead of the extracted folder; typed a path with a typo; used a path valid inside a container but not on the host; deleted the directory after configuring.","solutions":["Extract jdt-language-server-*.tar.gz from https://download.eclipse.org/jdtls/snapshots/ and set jdtls_path to the extracted directory.","Or run 'brew install jdtls' (macOS) and point jdtls_path at the installation prefix directory.","Verify the path with 'ls <jdtls_path>' from the same environment/user running Serena.","Use an absolute path to avoid working-directory ambiguity.","Confirm plugins/, config_<platform>/, features/ exist directly under jdtls_path."],"exampleFix":"// before\n\"jdtls_path\": \"/opt/jdt-language-server-latest.tar.gz\"\n// after\nmkdir -p /opt/jdtls && tar -xzf jdt-language-server-latest.tar.gz -C /opt/jdtls\n\"jdtls_path\": \"/opt/jdtls\"","handlingStrategy":"validation","validationCode":"import os\np = os.path.expanduser(settings['ls_specific_settings']['java']['jdtls_path'])\nassert os.path.isdir(p), f\"jdtls_path '{p}' is not a directory — extract the JDTLS tarball first\"","typeGuard":"def is_valid_jdtls_root(path: str) -> bool:\n    from pathlib import Path\n    root = Path(path).expanduser()\n    return root.is_dir() and (root / 'plugins').is_dir() and any(root.glob('config_*'))","tryCatchPattern":"try:\n    ls = SolidLSP(java_config)\nexcept SolidLSPException as e:\n    if 'not an existing directory' in str(e):\n        raise SystemExit(f\"Fix jdtls_path: {e}\")\n    raise","preventionTips":["Always expanduser() and absolutize jdtls_path in configuration.","Extract the tarball before wiring the path; verify with ls that plugins/ exists.","Never point jdtls_path at the .tar.gz file itself.","Use provisioning scripts that extract JDTLS and write the config in one step."],"tags":["java","jdtls","configuration","filesystem"],"backgroundTag":"path-not-found","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}