{"record":{"id":"b9fded1da1bd7b18","repo":"elastic/elasticsearch","slug":"task-can-t-use-test-cluster-from-another-projec","errorCode":null,"errorMessage":"Task {} can't use test cluster from another project {}","messagePattern":"Task (.+?) can't use test cluster from another project (.+?)","errorType":"exception","errorClass":"TestClustersException","httpStatus":null,"severity":"error","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersAware.java","lineNumber":36,"sourceCode":"import java.util.Collection;\n\nimport static org.elasticsearch.gradle.testclusters.TestClustersPlugin.REGISTRY_SERVICE_NAME;\nimport static org.elasticsearch.gradle.testclusters.TestClustersPlugin.TEST_CLUSTER_TASKS_SERVICE;\n\npublic interface TestClustersAware extends Task {\n\n    @Nested\n    Collection<ElasticsearchCluster> getClusters();\n\n    @ServiceReference(REGISTRY_SERVICE_NAME)\n    Property<TestClustersRegistry> getRegistry();\n\n    @ServiceReference(TEST_CLUSTER_TASKS_SERVICE)\n    Property<TestClustersPlugin.TaskEventsService> getTasksService();\n\n    default void useCluster(ElasticsearchCluster cluster) {\n        if (cluster.getPath().equals(getProject().getPath()) == false) {\n            throw new TestClustersException(\"Task \" + getPath() + \" can't use test cluster from\" + \" another project \" + cluster);\n        }\n        if (cluster.getName().equals(getName())) {\n            for (ElasticsearchNode node : cluster.getNodes()) {\n                for (ElasticsearchDistribution distro : node.getDistributions()) {\n                    ElasticsearchDistribution frozenDistro = distro.maybeFreeze();\n                    dependsOn(frozenDistro);\n                }\n            }\n            dependsOn(cluster.getPluginAndModuleConfigurations());\n        }\n        getClusters().add(cluster);\n    }\n\n    default Provider<TestClusterInfo> getClusterInfo(String clusterName) {\n        return getProject().getProviders().of(TestClusterValueSource.class, source -> {\n            source.getParameters().getService().set(getRegistry());\n            source.getParameters().getClusterName().set(clusterName);\n            source.getParameters().getPath().set(getProject().getIsolated().getPath());","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersAware.java#L18-L54","documentation":"TestClustersAware.useCluster() rejects registering a cluster whose Gradle project path differs from the task's own project path. Test clusters are build-scoped singletons owned by a project; a task in project `:a` cannot reference a cluster declared in project `:b` because lifecycle, cleanup, and `dependsOn` wiring all assume co-location. The check is by `cluster.getPath()` (the cluster's project) vs `getProject().getPath()`.","triggerScenarios":"Calling `task.useCluster(testClusters.<name>)` where `testClusters` resolves to a cluster container in a different subproject than the task. Common when referencing `rootProject.testClusters.x` or `project(':other').testclusters.x` from a task in the current project.","commonSituations":"Sharing a cluster across modules to save startup time (not supported); copy-pasting a `useCluster` line from a sibling module; applying a convention plugin that wires clusters defined in the root project into subproject tasks.","solutions":["Declare the `ElasticsearchCluster` in the SAME project as the task that calls `useCluster(...)`.","If you need an identical cluster shape in multiple projects, define it (or apply a convention that defines it) in each project — they are cheap to declare.","Move the task into the project that owns the cluster, or move the cluster declaration into the task's project.","Do NOT attempt to bridge via `rootProject` references — the guard exists precisely to prevent this."],"exampleFix":"// before: in :a/build.gradle\nuseCluster(rootProject.testClusters.shared)\n// after: declare locally\nElasticsearchCluster shared = testClusters.create('shared')\nuseCluster(shared)","handlingStrategy":"validation","validationCode":"if (!cluster.getPath().equals(task.getProject().getPath())) {\n  throw new TestClustersException(\n    \"Cluster must be declared in \" + task.getProject().getPath() + \"; it is in \" + cluster.getPath());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always declare testClusters in the same project as the tasks that use them.","Factor shared cluster SHAPE into a convention plugin applied per-project, not a shared instance.","Never reference `rootProject.testClusters.*` or `project(':other').testClusters.*` from a task."],"tags":["gradle","testclusters","multi-project","configuration","build-tools"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}