elastic/elasticsearch · error · GradleException

Sysprop [${property}] must be [true] or [false] but was [${p

Error message

Sysprop [${property}] must be [true] or [false] but was [${propertyValue}]

What it means

Util.getBooleanProperty reads a Java system property and only accepts the canonical strings "true" and "false"; unset falls back to the default. Anything else — yes, no, 1, 0, TRUE, empty — throws a GradleException naming the property and the bad value. This guards build switches against silent truthy/falsy coercion.

Source

Thrown at build-conventions/src/main/java/org/elasticsearch/gradle/internal/conventions/util/Util.java:42

import java.io.File;
import java.util.Optional;
import java.util.function.Supplier;

import javax.annotation.Nullable;

public class Util {

    public static boolean getBooleanProperty(String property, boolean defaultValue) {
        String propertyValue = System.getProperty(property);
        if (propertyValue == null) {
            return defaultValue;
        }
        if ("true".equals(propertyValue)) {
            return true;
        } else if ("false".equals(propertyValue)) {
            return false;
        } else {
            throw new GradleException("Sysprop [" + property + "] must be [true] or [false] but was [" + propertyValue + "]");
        }
    }

    /**
     * @param project The project to look for resources.
     * @param filter  Optional filter function to filter the returned resources
     * @return Returns the {@link FileTree} for main resources from Java projects. Returns null if no files exist.
     */
    @Nullable
    public static FileTree getJavaMainSourceResources(Project project, Action<? super PatternFilterable> filter) {
        final Optional<FileTree> mainFileTree = getJavaMainSourceSet(project).map(SourceSet::getResources).map(FileTree::getAsFileTree);
        return mainFileTree.map(files -> files.matching(filter)).orElse(null);
    }

    /**
     * @param project The project to look for resources.
     * @param filter  Optional filter function to filter the returned resources
     * @return Returns the {@link FileTree} for test resources from Java projects. Returns null if no files exist.

View on GitHub (pinned to db6a809a66)

Solutions

  1. Set the property to exactly true or false.
  2. Leave it unset to take the default.
  3. Fix the upstream env-to-sysprop mapping to canonicalise before passing to Gradle.

Example fix

// before
./gradlew build -Dtests.leaks=1
// after
./gradlew build -Dtests.leaks=true
Defensive patterns

Strategy: validation

Validate before calling

static boolean canonicalBoolean(String property, boolean defaultValue) {
    String v = System.getProperty(property);
    if (v == null) return defaultValue;
    if ("true".equals(v)) return true;
    if ("false".equals(v)) return false;
    throw new GradleException("Sysprop [" + property + "] must be [true] or [false] but was [" + v + "]");
}

Type guard

static boolean isCanonicalBoolean(String s) {
    return "true".equals(s) || "false".equals(s);
}

Prevention

When it happens

Trigger: Calling Util.getBooleanProperty(name, default) while -D<name> is set to a non-canonical boolean string. Common call sites in this repo read feature-flag and behaviour sysprops during configuration.

Common situations: A CI matrix exporting booleans as 1/0 or yes/no that get mapped verbatim onto the sysprop; a wrapper script uppercasing values; a user passing -Dfoo=True expecting case-insensitivity.

Related errors


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