elastic/elasticsearch · error · InvalidUserDataException

Invalid tests.bwc.mode value [${mode}]. Must be one of: grad

Error message

Invalid tests.bwc.mode value [${mode}]. Must be one of: gradle, dra, auto

What it means

Thrown as InvalidUserDataException by validateBwcMode() when the tests.bwc.mode system property is not one of 'gradle', 'dra', or 'auto'. The validator runs at configuration time to give users a clear, immediate error rather than a silent no-op or cryptic downstream failure. 'gradle' forces source builds, 'dra' forces DRA downloads, 'auto' tries DRA then falls back.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionBwcSetupPlugin.java:673

                    if (expectedOutputFile.exists() == false) {
                        Path relativeOutputPath = rootDir.toPath().relativize(expectedOutputFile.toPath());
                        throw new InvalidUserDataException(
                            "Downloading %s from DRA didn't produce expected artifact [%s].".formatted(bwcVersion.get(), relativeOutputPath)
                        );
                    }
                });
            });
        }
        bwcTaskProvider.configure(t -> t.dependsOn(bwcTaskName));
    }

    /**
     * Validates the {@code tests.bwc.mode} value, throwing {@link InvalidUserDataException} for
     * unrecognised values so users get a clear error message rather than a silent no-op.
     */
    static void validateBwcMode(String mode) {
        if (Set.of("gradle", "dra", "auto").contains(mode) == false) {
            throw new InvalidUserDataException("Invalid tests.bwc.mode value [" + mode + "]. Must be one of: gradle, dra, auto");
        }
    }

    /**
     * Returns the human-readable log message to emit when the gradle source-build fallback is
     * taken.  The message varies by mode (to explain <em>why</em> the fallback occurred) and by
     * artifact type (distribution archive vs. Maven JAR).
     *
     * <p>Extracted as a package-private static method so it can be exercised by unit tests without
     * standing up a full Gradle project.
     */
    static String buildFallbackMessage(String bwcMode, boolean isDistributionArchive, String bwcVersion, String projectName) {
        String draUnavailable = " — tests.bwc.mode=dra but no DRA snapshot was available"
            + " (endpoint unreachable or no build for this branch yet); falling back to source build";
        if (isDistributionArchive) {
            return switch (bwcMode) {
                case "dra" -> "BWC [" + bwcVersion + "]: building distribution [" + projectName + "] from source" + draUnavailable;
                case "auto" -> "BWC ["

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use exactly one of: gradle, dra, auto (lowercase). Example: -Dtests.bwc.mode=auto.
  2. If unsure which to use, pick 'auto' — it tries DRA first and falls back to gradle.
  3. Check for trailing spaces or quotes in the shell variable feeding the property.

Example fix

# before
./gradlew bwcTest -Dtests.bwc.mode=source

# after
./gradlew bwcTest -Dtests.bwc.mode=gradle
Defensive patterns

Strategy: validation

Validate before calling

String mode = System.getProperty("tests.bwc.mode", "auto");
if (Set.of("gradle", "dra", "auto").contains(mode) == false) {
    throw new IllegalArgumentException("Invalid tests.bwc.mode: " + mode + ". Use gradle, dra, or auto.");
}

Prevention

When it happens

Trigger: validateBwcMode(mode) at line 671 checks Set.of("gradle", "dra", "auto").contains(mode). Any other value — 'source', 'snapshot', empty string, typo like 'auto ' (trailing space), or 'DRA' (wrong case) — throws immediately.

Common situations: Developer guesses the property value (-Dtests.bwc.mode=source); CI config has a typo or stale value; copy-paste from docs with wrong case; trailing whitespace from shell expansion.

Related errors


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