gradle/gradle · error · InvalidUserDataException

'{taskName}.groovyClasspath' must not be empty. If a Groovy

Error message

'{taskName}.groovyClasspath' must not be empty. If a Groovy compile dependency is provided, the 'groovy-base' plugin will attempt to configure 'groovyClasspath' automatically. Alternatively, you may configure 'groovyClasspath' explicitly.

What it means

GroovyCompile needs the Groovy distribution (compiler + runtime jars) on groovyClasspath to run. The groovy-base plugin normally infers it from the 'groovy' configuration; checkGroovyClasspathIsNonEmpty throws InvalidUserDataException when that inference produced an empty classpath at execution time.

Source

Thrown at platforms/jvm/language-groovy/src/main/java/org/gradle/api/tasks/compile/GroovyCompile.java:288

        if (sourceCompatibility == null) {
            sourceCompatibility = toolchainVersion;
        }
        String targetCompatibility = getTargetCompatibility();
        if (targetCompatibility == null) {
            targetCompatibility = sourceCompatibility;
        }

        spec.setSourceCompatibility(sourceCompatibility);
        spec.setTargetCompatibility(targetCompatibility);
    }

    private JavaInstallationMetadata getToolchain() {
        return getJavaLauncher().map(JavaLauncher::getMetadata).get();
    }

    private void checkGroovyClasspathIsNonEmpty() {
        if (getGroovyClasspath().isEmpty()) {
            throw new InvalidUserDataException("'" + getName() + ".groovyClasspath' must not be empty. If a Groovy compile dependency is provided, "
                + "the 'groovy-base' plugin will attempt to configure 'groovyClasspath' automatically. Alternatively, you may configure 'groovyClasspath' explicitly.");
        }
    }

    /**
     * We need to track the Java version of the JVM the Groovy compiler is running on, since the Groovy compiler produces different results depending on it.
     *
     * This should be replaced by a property on the Groovy toolchain as soon as we model these.
     *
     * @since 4.0
     */
    @Input
    protected String getGroovyCompilerJvmVersion() {
        return getToolchain().getLanguageVersion().toString();
    }

    /**
     * {@inheritDoc}

View on GitHub (pinned to 534f27719b)

Solutions

  1. Declare a Groovy dependency: dependencies { groovy 'org.apache.groovy:groovy:4.0.21' } or groovy localGroovy()
  2. Or configure the task directly: tasks.named('compileGroovy') { groovyClasspath = files('/path/to/groovy-all.jar') }
  3. Check nothing removes dependencies from the groovy configuration (configuration filtering, resolutionStrategy overrides)

Example fix

// before
plugins { id 'groovy' } // no groovy dependency -> empty groovyClasspath
// after
plugins { id 'groovy' }
dependencies { groovy localGroovy() } // or org.apache.groovy:groovy:4.0.21
Defensive patterns

Strategy: validation

Validate before calling

afterEvaluate {
  def groovyCfg = configurations.findByName('groovy')
  if (groovyCfg == null || groovyCfg.dependencies.empty) {
    dependencies.add('groovy', dependencies.localGroovy())
  }
}

Prevention

When it happens

Trigger: Running a GroovyCompile task when groovyClasspath resolves empty: no dependency on the groovy configuration, a manually created GroovyCompile task never given groovyClasspath, or build logic that cleared/replaced the groovy configuration after evaluation.

Common situations: Applying the groovy plugin but declaring groovy only as implementation from a repository that failed; hand-rolled tasks.withType(GroovyCompile) tasks in a plugin; excluding the groovy dependency for artifact-size reasons.

Related errors


AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22). Data as JSON: /api/errors/3d7fccf94903caa8. Report an issue: GitHub.