{"record":{"id":"100e3569113878ba","repo":"elastic/elasticsearch","slug":"cannot-shrink-to-have-nodes-as-it-already-ha","errorCode":null,"errorMessage":"Cannot shrink {} to have {} nodes as it already has {}","messagePattern":"Cannot shrink (.+?) to have (.+?) nodes as it already has (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchCluster.java","lineNumber":177,"sourceCode":"    public FileCollection getInstalledClasspath() {\n        return pluginAndModuleConfiguration.getAsFileTree().filter(f -> f.getName().endsWith(\".jar\"));\n    }\n\n    @InputFiles\n    @PathSensitive(PathSensitivity.RELATIVE)\n    public FileCollection getInstalledFiles() {\n        return pluginAndModuleConfiguration.getAsFileTree().filter(f -> f.getName().endsWith(\".jar\") == false);\n    }\n\n    public void setNumberOfNodes(int numberOfNodes) {\n        checkFrozen();\n\n        if (numberOfNodes < 1) {\n            throw new IllegalArgumentException(\"Number of nodes should be >= 1 but was \" + numberOfNodes + \" for \" + this);\n        }\n\n        if (numberOfNodes < nodes.size()) {\n            throw new IllegalArgumentException(\n                \"Cannot shrink \" + this + \" to have \" + numberOfNodes + \" nodes as it already has \" + getNumberOfNodes()\n            );\n        }\n\n        for (int i = nodes.size(); i < numberOfNodes; i++) {\n            this.nodes.add(\n                new ElasticsearchNode(\n                    safeName(clusterName),\n                    path,\n                    clusterName + \"-\" + i,\n                    project,\n                    reaper,\n                    testClustersRegistryProvider,\n                    fileSystemOperations,\n                    archiveOperations,\n                    execOperations,\n                    fileOperations,\n                    workingDirBase,","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchCluster.java#L159-L195","documentation":"Thrown by ElasticsearchCluster.setNumberOfNodes when the requested count is smaller than the number of nodes already in the cluster. The list only grows (new ElasticsearchNode entries are appended in the loop below); shrinking is not supported because removing running nodes from a test cluster is unsafe.","triggerScenarios":"A cluster already has N nodes (added via prior setNumberOfNodes or node {} blocks) and a later setNumberOfNodes(M) call has M < N.","commonSituations":"Two test tasks share a cluster spec but request different sizes; a setup hook sets a higher count then a per-test override tries to lower it; dynamic resizing based on a parameter that decreased between runs.","solutions":["Only ever increase numberOfNodes for a given cluster instance; declare separate testClusters blocks if different sizes are needed.","Audit ordering of setNumberOfNodes calls — move the largest required size to the earliest point.","If a smaller cluster is genuinely needed, define a distinct testCluster (e.g. testClusters { small {} }) rather than reusing one."],"exampleFix":"// before\ntestClusters {\n  numberOfNodes = 3\n}\ntasks.named('integTest').configure {\n  // later, in a different task reusing the same cluster\n  doFirst { testClusters.cluster.numberOfNodes = 1 }  // throws\n}\n\n// after\ntestClusters {\n  big { numberOfNodes = 3 }\n  small { numberOfNodes = 1 }\n}\ntasks.named('integTestBig').configure { useCluster testClusters.big }\ntasks.named('integTestSmall').configure { useCluster testClusters.small }","handlingStrategy":"validation","validationCode":"int current = cluster.getNumberOfNodes();\nif (requested < current) {\n    throw new IllegalStateException(\"Refusing to shrink cluster \" + current + \" -> \" + requested);\n}\ncluster.setNumberOfNodes(requested);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat numberOfNodes as monotonically increasing per cluster instance.","Use distinct testClusters blocks for distinct sizes.","Centralize the largest required size and set it once."],"tags":["test","testclusters","configuration","validation"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}