elastic/elasticsearch · error · IllegalArgumentException

Same version specified to add and remove

Error message

Same version specified to add and remove

What it means

Thrown by UpdateVersionsTask.executeTask() when addVersion and removeVersion are both set and are equal. Adding and removing the same version in one run is contradictory and is rejected up front.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/UpdateVersionsTask.java:97

    static Optional<Version> parseVersionField(CharSequence field) {
        Matcher m = VERSION_FIELD.matcher(field);
        if (m.find() == false) return Optional.empty();

        return Optional.of(
            new Version(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)), Integer.parseInt(m.group(3)), m.group(4))
        );
    }

    @TaskAction
    public void executeTask() throws IOException {
        if (addVersion == null && removeVersion == null) {
            throw new IllegalArgumentException("No versions to add or remove specified");
        }
        if (setCurrent && addVersion == null) {
            throw new IllegalArgumentException("No new version added to set as the current version");
        }
        if (addVersion != null && removeVersion != null && Objects.equals(addVersion, removeVersion)) {
            throw new IllegalArgumentException("Same version specified to add and remove");
        }

        Path versionJava = rootDir.resolve(VERSION_FILE_PATH);
        CompilationUnit file = LexicalPreservingPrinter.setup(StaticJavaParser.parse(versionJava));

        Optional<CompilationUnit> modifiedFile = Optional.empty();
        if (addVersion != null) {
            LOGGER.lifecycle("Adding new version [{}] to [{}]", addVersion, versionJava);
            var added = addVersionConstant(modifiedFile.orElse(file), addVersion, setCurrent);
            if (added.isPresent()) {
                modifiedFile = added;
            }
        }
        if (removeVersion != null) {
            LOGGER.lifecycle("Removing version [{}] from [{}]", removeVersion, versionJava);
            var removed = removeVersionConstant(modifiedFile.orElse(file), removeVersion);
            if (removed.isPresent()) {
                modifiedFile = removed;

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use distinct versions for --add-version and --remove-version.
  2. If only one operation is intended, omit the other option.

Example fix

// before
./gradlew updateVersions --add-version=8.10.0 --remove-version=8.10.0

// after
./gradlew updateVersions --add-version=8.10.0 --remove-version=8.9.0
Defensive patterns

Strategy: validation

Validate before calling

// Reject contradictory add/remove of the same version early
String add = providers.gradleProperty("add-version").getOrElse(null);
String remove = providers.gradleProperty("remove-version").getOrElse(null);
if (add != null && add.equals(remove)) {
    throw new GradleException("--add-version and --remove-version must differ");
}

Prevention

When it happens

Trigger: Passing the same version string to both --add-version and --remove-version.

Common situations: A templated command reused the same variable for both options; a copy-paste error in the release command.

Related errors


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