{"record":{"id":"91e234436611e511","repo":"gradle/gradle","slug":"the-specified-s-does-not-appear-to-contain-a-grad","errorCode":null,"errorMessage":"The specified %s does not appear to contain a Gradle distribution.","messagePattern":"The specified (.+?) does not appear to contain a Gradle distribution\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"platforms/ide/tooling-api/src/main/java/org/gradle/tooling/internal/consumer/DistributionFactory.java","lineNumber":160,"sourceCode":"        @Override\n        public String getDisplayName() {\n            return displayName;\n        }\n\n        @Override\n        public ClassPath getToolingImplementationClasspath(ProgressLoggerFactory progressLoggerFactory, InternalBuildProgressListener progressListener, ConnectionParameters connectionParameters, BuildCancellationToken cancellationToken) {\n            if (!gradleHomeDir.exists()) {\n                throw new IllegalArgumentException(String.format(\"The specified %s does not exist.\", locationDisplayName));\n            }\n            if (!gradleHomeDir.isDirectory()) {\n                throw new IllegalArgumentException(String.format(\"The specified %s is not a directory.\", locationDisplayName));\n            }\n            // The lib directory implements a cross-gradle-version contract, where the\n            // TAPI consumer will load the TAPI provider classpath from the\n            // `lib` directory of the target gradle distribution.\n            File libDir = new File(gradleHomeDir, \"lib\");\n            if (!libDir.isDirectory()) {\n                throw new IllegalArgumentException(String.format(\"The specified %s does not appear to contain a Gradle distribution.\", locationDisplayName));\n            }\n            File[] files = libDir.listFiles(new FileFilter() {\n                @Override\n                public boolean accept(File file) {\n                    return hasExtension(file, \".jar\");\n                }\n            });\n            // Make sure file order is always consistent\n            Arrays.sort(files);\n            return DefaultClassPath.of(files);\n        }\n    }\n\n}\n","sourceCodeStart":142,"sourceCodeEnd":175,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/ide/tooling-api/src/main/java/org/gradle/tooling/internal/consumer/DistributionFactory.java#L142-L175","documentation":"The third validation in InstalledDistribution: the Tooling API loads the provider classpath from the lib/ directory of the target distribution (a cross-Gradle-version contract). If gradleHomeDir exists and is a directory but has no lib/ subdirectory, the path is not a Gradle distribution layout and this IllegalArgumentException is thrown ('The specified ... does not appear to contain a Gradle distribution.').","triggerScenarios":"useInstallation(...) pointed at a directory that is not a distribution: a git clone of gradle/gradle, a partially extracted archive, or the parent folder one level above/below the real install root (e.g. /opt instead of /opt/gradle-8.7).","commonSituations":"Custom download logic that extracts only part of the ZIP; wrappers that store distributions in non-standard layouts; pointing at GRADLE_USER_HOME (~/.gradle) which contains caches but no lib/.","solutions":["Point useInstallation() at a complete Gradle distribution: the directory that directly contains bin/ and lib/ (e.g. /opt/gradle-8.7 from gradle-8.7-bin.zip).","Re-download and fully extract the distribution, then verify ls <dir>/lib lists the gradle-*.jar files.","If you meant the wrapper-managed distribution, remove useInstallation and let the wrapper resolve it instead."],"exampleFix":"# before\nconnector.useInstallation(new File(\"/opt\"));            # contains gradle-8.7/ but no lib/\nconnector.useInstallation(new File(\"/opt/gradle-8.7/lib\")); # wrong level\n\n# after\nconnector.useInstallation(new File(\"/opt/gradle-8.7\"));    # contains bin/ and lib/","handlingStrategy":"validation","validationCode":"static boolean looksLikeGradleDistribution(Path dir) throws IOException {\n    Path lib = dir.resolve(\"lib\");\n    if (!Files.isDirectory(lib)) return false;\n    try (Stream<Path> jars = Files.list(lib)) {\n        return jars.anyMatch(p -> p.toString().endsWith(\".jar\"));\n    }\n}\n// before useInstallation(dir): if (!looksLikeGradleDistribution(dir)) throw new ConfigurationError(dir + \" has no lib/ with jars - not a Gradle distribution\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["After any custom download/extract step, assert <install>/lib contains gradle-*.jar before using the install.","Point useInstallation at the directory directly containing bin/ and lib/, exactly one level above lib/.","Do not use GRADLE_USER_HOME, a source checkout, or partial extractions as an installation."],"tags":["gradle","tooling-api","distribution","installation","layout"],"backgroundTag":"invalid-installation-directory","analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}