{"record":{"id":"54f8c7c8a7f3f770","repo":"quarkusio/quarkus","slug":"one-of-either-visitorfunction-or-inputtransformer","errorCode":null,"errorMessage":"One of either visitorFunction or inputTransformer must be set","messagePattern":"One of either visitorFunction or inputTransformer must be set","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/deployment/src/main/java/io/quarkus/deployment/builditem/BytecodeTransformerBuildItem.java","lineNumber":100,"sourceCode":"        this.requireConstPoolEntry = requireConstPoolEntry;\n        this.cacheable = cacheable;\n        this.inputTransformer = null;\n        this.classReaderOptions = 0;\n        this.continueOnFailure = false;\n        this.priority = 0;\n    }\n\n    public BytecodeTransformerBuildItem(Builder builder) {\n        this.classToTransform = builder.classToTransform;\n        this.visitorFunction = builder.visitorFunction;\n        this.requireConstPoolEntry = builder.requireConstPoolEntry;\n        this.cacheable = builder.cacheable;\n        this.inputTransformer = builder.inputTransformer;\n        this.classReaderOptions = builder.classReaderOptions;\n        this.continueOnFailure = builder.continueOnFailure;\n        this.priority = builder.priority;\n        if (visitorFunction == null && inputTransformer == null) {\n            throw new IllegalArgumentException(\"One of either visitorFunction or inputTransformer must be set\");\n        }\n    }\n\n    public String getClassToTransform() {\n        return classToTransform;\n    }\n\n    public BiFunction<String, ClassVisitor, ClassVisitor> getVisitorFunction() {\n        return visitorFunction;\n    }\n\n    public Set<String> getRequireConstPoolEntry() {\n        return requireConstPoolEntry;\n    }\n\n    public boolean isCacheable() {\n        return cacheable;\n    }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/deployment/src/main/java/io/quarkus/deployment/builditem/BytecodeTransformerBuildItem.java#L82-L118","documentation":"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.","triggerScenarios":"Building BytecodeTransformerBuildItem via its builder without calling either visitorFunction(...) or inputTransformer(...); conditionally setting the transformer so that on some paths neither is set.","commonSituations":"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.","solutions":["Call visitorFunction((className, visitor) -> ...) or inputTransformer(bytes -> ...) on the builder, whichever transformation style you need.","If transformation is optional, only produce the build item when a transformer is actually configured.","Guard the builder path with an assertion that exactly one of the two is set before building."],"exampleFix":"// before\nBytecodeTransformerBuildItem item = new BytecodeTransformerBuildItem(\n    new BytecodeTransformerBuildItem.Builder(\"com.app.Foo\"));\n// after\nBytecodeTransformerBuildItem item = new BytecodeTransformerBuildItem(\n    new BytecodeTransformerBuildItem.Builder(\"com.app.Foo\")\n        .visitorFunction((cls, visitor) -> new MyClassVisitor(visitor)));","handlingStrategy":"validation","validationCode":"if (builder.visitorFunction == null && builder.inputTransformer == null) {\n    throw new IllegalStateException(\"Set visitorFunction or inputTransformer on BytecodeTransformerBuildItem\");\n}","typeGuard":"static boolean isTransformable(BytecodeTransformerBuildItem.Builder b) {\n    return b.visitorFunction != null ^ b.inputTransformer != null; // exactly one set\n}","tryCatchPattern":null,"preventionTips":["Always set one transformation function in every builder path, including conditional branches.","Only produce the build item when a transformer is configured.","Add unit tests covering all conditional branches of transformation setup."],"tags":["bytecode","build-step","quarkus","builder"],"backgroundTag":"missing-required-transformer","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}