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
- Pass a concrete TransformAction class literal: dependencies.registerTransform(MinifyAction) { ... }
- If the class comes from configuration or a lookup, null-check it and fail with your own descriptive message before calling registerTransform
- 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
- Prefer class literals over name-based lookups when calling registerTransform
- Fail with your own message when an optional transform class is not configured
- Log which transform class is being registered in plugin debug output
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
- Null value provided in parameters %s
- Unexpected marker file: {markerFile} in instrumented buildsc
- Cannot fetch a model of type '%s' as this type is not an int
- Direct instantiation of a BaseLanguageSourceSet is not permi
- Direct instantiation of a BaseBinarySpec is not permitted. U
AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22).
Data as JSON: /api/errors/a84b7325a30df6b2.
Report an issue: GitHub.