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
- Register all resources during the configuration phase, directly in the build script or plugin apply, not in a doFirst/doLast.
- Avoid holding task references and mutating them after the task graph executes.
- 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
- Register all resources during the configuration phase only.
- Never call task mutation methods from doFirst/doLast/afterEvaluate that run post-execution.
- Use lazy Providers/Properties if late-bound inputs are required.
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
- Unable to find build service with name '{}'.
- elasticsearch.standalone-test, elasticsearch.standalone-rest
- platform cannot be set on elasticsearch distribution [${name
- bundledJdk cannot be set on elasticsearch distribution [${na
- ${className} does not support remove()
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/c66a62c030833acd.
Report an issue: GitHub.