gradle/gradle · error · IllegalArgumentException

An artifact transform action type must be provided.

Error message

An artifact transform action type must be provided.

What it means

registerTransform requires the Class of a TransformAction implementation; DefaultVariantTransformRegistry.validateActionType fails fast with this IllegalArgumentException when the action type argument is null, before any registration work starts. In practice null arrives from plugin/configuration code (an unset class property, a failed lookup) rather than a literal null literal in a build script.

Source

Thrown at platforms/software/dependency-management/src/main/java/org/gradle/api/internal/artifacts/transform/DefaultVariantTransformRegistry.java:124

                formatter.append("from ");
                formatter.appendValue(registration.from);
            }
            if (!registration.to.isEmpty()) {
                if (!registration.from.isEmpty()) {
                    formatter.append(" ");
                }
                formatter.append("to ");
                formatter.appendValue(registration.to);
            }
            formatter.append(")");
        }
        formatter.append(".");
        return formatter.toString();
    }

    private <T> void validateActionType(@Nullable Class<T> actionType) {
        if (actionType == null) {
            throw new IllegalArgumentException("An artifact transform action type must be provided.");
        }
    }

    @NonExtensible
    public static abstract class TypedRegistration<T extends TransformParameters> implements TransformSpec<T> {
        private final AttributeContainerInternal from;
        private final AttributeContainerInternal to;
        private final T parameterObject;

        @Inject
        protected abstract DocumentationRegistry getDocumentationRegistry();

        public TypedRegistration(T parameterObject, AttributesFactory attributesFactory) {
            this.parameterObject = parameterObject;
            this.from = attributesFactory.mutable();
            this.to = attributesFactory.mutable();
        }

View on GitHub (pinned to 534f27719b)

Solutions

  1. Pass a concrete TransformAction class literal: dependencies.registerTransform(MinifyAction) { ... }
  2. If the class comes from configuration or a lookup, null-check it and fail with your own descriptive message before calling registerTransform
  3. Fix the lookup that produced null (typo in the class name or map key)

Example fix

// before
def actionClass = transformClassesByName[extension.transformName] // null: unknown name
dependencies.registerTransform(actionClass) { it.to.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE, 'min') }

// after
def actionClass = transformClassesByName[extension.transformName]
    ?: throw new GradleException("Unknown transform '${extension.transformName}'. Available: ${transformClassesByName.keySet()}")
dependencies.registerTransform(actionClass) { it.to.attribute(ArtifactTypeDefinition.ARTIFACT_TYPE, 'min') }
Defensive patterns

Strategy: validation

Validate before calling

// before calling registerTransform with a dynamic class
def actionClass = transformClassesByName[name]
if (actionClass == null) {
    throw new GradleException("Unknown transform '${name}'. Available: ${transformClassesByName.keySet()}")
}

Type guard

// Java: narrow and validate the action class before registration
static Class<? extends TransformAction<?>> asTransformAction(Class<?> c) {
    Objects.requireNonNull(c, "transform action class must not be null");
    if (!TransformAction.class.isAssignableFrom(c)) {
        throw new IllegalArgumentException(c + " does not implement TransformAction");
    }
    return c.asSubclass(TransformAction.class);
}

Prevention

When it happens

Trigger: Calling dependencies.registerTransform(null) { ... }; passing a Class property from a plugin extension that was never set; resolving the class from a name-to-class map whose key is missing and handing the null result to registerTransform.

Common situations: Plugins that let users configure which transform class to apply and the user did not configure it; class-forName lookups with typos returning null; conditional registration code referencing an unset variable.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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