quarkusio/quarkus · error · IllegalArgumentException

One of either visitorFunction or inputTransformer must be se

Error message

One of either visitorFunction or inputTransformer must be set

What it means

BytecodeTransformerBuildItem must supply at least one way to transform the class: either a visitorFunction (ASM visitor-based transformation) or an inputTransformer (byte[] -> byte[]). The constructor rejects instances with neither, since the build item would be a no-op.

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/builditem/BytecodeTransformerBuildItem.java:100

        this.requireConstPoolEntry = requireConstPoolEntry;
        this.cacheable = cacheable;
        this.inputTransformer = null;
        this.classReaderOptions = 0;
        this.continueOnFailure = false;
        this.priority = 0;
    }

    public BytecodeTransformerBuildItem(Builder builder) {
        this.classToTransform = builder.classToTransform;
        this.visitorFunction = builder.visitorFunction;
        this.requireConstPoolEntry = builder.requireConstPoolEntry;
        this.cacheable = builder.cacheable;
        this.inputTransformer = builder.inputTransformer;
        this.classReaderOptions = builder.classReaderOptions;
        this.continueOnFailure = builder.continueOnFailure;
        this.priority = builder.priority;
        if (visitorFunction == null && inputTransformer == null) {
            throw new IllegalArgumentException("One of either visitorFunction or inputTransformer must be set");
        }
    }

    public String getClassToTransform() {
        return classToTransform;
    }

    public BiFunction<String, ClassVisitor, ClassVisitor> getVisitorFunction() {
        return visitorFunction;
    }

    public Set<String> getRequireConstPoolEntry() {
        return requireConstPoolEntry;
    }

    public boolean isCacheable() {
        return cacheable;
    }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Call visitorFunction((className, visitor) -> ...) or inputTransformer(bytes -> ...) on the builder, whichever transformation style you need.
  2. If transformation is optional, only produce the build item when a transformer is actually configured.
  3. Guard the builder path with an assertion that exactly one of the two is set before building.

Example fix

// before
BytecodeTransformerBuildItem item = new BytecodeTransformerBuildItem(
    new BytecodeTransformerBuildItem.Builder("com.app.Foo"));
// after
BytecodeTransformerBuildItem item = new BytecodeTransformerBuildItem(
    new BytecodeTransformerBuildItem.Builder("com.app.Foo")
        .visitorFunction((cls, visitor) -> new MyClassVisitor(visitor)));
Defensive patterns

Strategy: validation

Validate before calling

if (builder.visitorFunction == null && builder.inputTransformer == null) {
    throw new IllegalStateException("Set visitorFunction or inputTransformer on BytecodeTransformerBuildItem");
}

Type guard

static boolean isTransformable(BytecodeTransformerBuildItem.Builder b) {
    return b.visitorFunction != null ^ b.inputTransformer != null; // exactly one set
}

Prevention

When it happens

Trigger: Building BytecodeTransformerBuildItem via its builder without calling either visitorFunction(...) or inputTransformer(...); conditionally setting the transformer so that on some paths neither is set.

Common situations: Code generation/transformation build steps where the transformer is set behind an if branch that is skipped; refactoring from visitorFunction to inputTransformer and dropping both; copy-pasted builder code with the wrong method name.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/54f8c7c8a7f3f770. Report an issue: GitHub.