elastic/elasticsearch · error · GradleException

buildResources can't be configured after the task ran. Make

Error message

buildResources can't be configured after the task ran. Make sure task is not used after configuration time

What it means

Thrown by ExportElasticsearchBuildResourcesTask.copy when the task has already executed or is currently executing (getState().getExecuted() || getState().getExecuting()). Resource registration must happen during Gradle's configuration phase; calling copy(...) after the task graph ran is a configuration-vs-execution misuse.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ExportElasticsearchBuildResourcesTask.java:89

    }

    public void setOutputDir(File outputDir) {
        this.outputDir.set(outputDir);
    }

    /**
     * Copy a resource to the output directory, keeping the original filename.
     */
    public void copy(String resource) {
        copy(resource, resource);
    }

    /**
     * Copy a resource to the output directory with a different filename.
     */
    public void copy(String resource, String destName) {
        if (getState().getExecuted() || getState().getExecuting()) {
            throw new GradleException(
                "buildResources can't be configured after the task ran. " + "Make sure task is not used after configuration time"
            );
        }
        resources.put(resource, destName);
    }

    @TaskAction
    public void doExport() {
        if (resources.isEmpty()) {
            setDidWork(false);
            throw new StopExecutionException();
        }
        resources.entrySet().stream().parallel().forEach(entry -> {
            String resourcePath = entry.getKey();
            String destName = entry.getValue();
            Path destination = outputDir.get().file(destName).getAsFile().toPath();
            try (InputStream is = getClass().getClassLoader().getResourceAsStream(resourcePath)) {
                Files.createDirectories(destination.getParent());

View on GitHub (pinned to db6a809a66)

Solutions

  1. Register all resources during the configuration phase, directly in the build script or plugin apply, not in a doFirst/doLast.
  2. Avoid holding task references and mutating them after the task graph executes.
  3. If late binding is needed, use a Provider/Property so configuration is lazy.

Example fix

// before
myExportTask.doFirst { t -> t.copy('extra.txt') }
// after
myExportTask.copy('extra.txt')  // at configuration time
Defensive patterns

Strategy: validation

Validate before calling

if (getState().getExecuted() || getState().getExecuting()) {
    throw new GradleException("buildResources can't be configured after the task ran.");
}

Prevention

When it happens

Trigger: Invoking task.copy(resource) from an afterEvaluate, doFirst, doLast, or another task's action that runs after this task has executed.

Common situations: Wiring resource export inside an action closure rather than at configuration time; reusing a task instance across builds in the same daemon.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/c66a62c030833acd. Report an issue: GitHub.