gradle/gradle · error · IllegalArgumentException

A %s needs to be specified for the %s.

Error message

A %s needs to be specified for the %s.

What it means

Dimensions.extractAndValidate() finalizes a component's declared dimension sets (buildTypes, linkages, targetMachines) and assertNonEmpty throws IllegalArgumentException 'A <propertyName> needs to be specified for the <componentName>.' when a set is empty - variant calculation requires at least one value on every dimension.

Source

Thrown at platforms/native/language-native/src/main/java/org/gradle/language/nativeplatform/internal/Dimensions.java:110

                                           AttributesFactory attributesFactory,
                                           Provider<String> group, Provider<String> version,
                                           Action<NativeVariantIdentity> action) {
        Collection<BuildType> buildTypes = BuildType.DEFAULT_BUILD_TYPES;
        Collection<Linkage> linkages = extractAndValidate("linkage", "library", declaredLinkages);
        Collection<TargetMachine> targetMachines = extractAndValidate("target machine", "library", declaredTargetMachines);
        variants(baseName, buildTypes, linkages, targetMachines, attributesFactory, group, version, action);
    }

    private static <T> Collection<T> extractAndValidate(String propertyName, String componentName, SetProperty<T> declared) {
        declared.finalizeValue();
        Collection<T> value = declared.get();
        assertNonEmpty(propertyName, componentName, value);
        return value;
    }

    private static void assertNonEmpty(String propertyName, String componentName, Collection<?> property) {
        if (property.isEmpty()) {
            throw new IllegalArgumentException(String.format("A %s needs to be specified for the %s.", propertyName, componentName));
        }
    }

    private static void validateTargetMachines(Collection<TargetMachine> testTargetMachines, Collection<TargetMachine> mainTargetMachines) {
        for (TargetMachine machine : testTargetMachines) {
            if (!mainTargetMachines.contains(machine)) {
                throw new IllegalArgumentException("The target machine " + machine.toString() + " was specified for the unit test, but this target machine was not specified on the component under test.");
            }
        }
    }

    private static void variants(Provider<String> baseName, Collection<BuildType> buildTypes, Collection<Linkage> linkages, Collection<TargetMachine> targetMachines,
                                 AttributesFactory attributesFactory,
                                 // TODO: These should come from somewhere else, probably
                                 Provider<String> group, Provider<String> version,
                                 Action<NativeVariantIdentity> action) {
        for (BuildType buildType : buildTypes) {
            for (Linkage linkage : linkages) {

View on GitHub (pinned to 534f27719b)

Solutions

  1. Keep at least one value per dimension: e.g. targetMachines = [machines.host()] or machines.windows.x86_64 instead of an empty list.
  2. If the intent was to disable building, don't empty a dimension - remove/avoid applying the component or its publish/plugin instead.
  3. Validate the sets in your own configuration code right after assignment so the error surfaces with your own context.

Example fix

// before: empty dimension -> IllegalArgumentException when variants are calculated
library.targetMachines = []

// after: explicit single target
library.targetMachines = [machines.host()]
Defensive patterns

Strategy: validation

Validate before calling

// Validate dimensions right after configuring the component:
assert !library.targetMachines.empty : 'targetMachines must not be empty'
assert !library.buildTypes.empty : 'buildTypes must not be empty'
// or set explicit values instead of clearing:
library.targetMachines = [machines.host()]

Prevention

When it happens

Trigger: Clearing or never populating a dimension on a native component before binaries are calculated: e.g. library.targetMachines = [] in build.gradle, an empty buildTypes = [] set, or linkages = [] - the failure fires when the plugin computes variants for the component.

Common situations: Trying to 'disable' a library by emptying its target machines or linkages; assigning targetMachines = [ ] instead of targetMachines.set([host()]) by mistake; a plugin computing per-component dimensions from an empty config list.

Related errors


AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22). Data as JSON: /api/errors/5ffba1c03916537c. Report an issue: GitHub.