{"record":{"id":"687c0483eca868d2","repo":"quarkusio/quarkus","slug":"method-method-of-interface-interface-is-not-687c04","errorCode":null,"errorMessage":"Method ${method} of interface ${interface} is not a getter method since it returns void","messagePattern":"Method (.+?) of interface (.+?) is not a getter method since it returns void","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/DerivedMethodsAdder.java","lineNumber":441,"sourceCode":"\n        ClassInfo interfaceInfo = index.getClassByName(interfaceName);\n\n        Gizmo gizmo = Gizmo.create(nonBeansClassOutput);\n        gizmo.class_(implName.toString(), implClassCreator -> {\n            implClassCreator.implements_(ClassDesc.of(interfaceName.toString()));\n\n            // Add default constructor\n            implClassCreator.defaultConstructor();\n\n            Map<String, FieldDesc> fields = new HashMap<>(3);\n\n            for (MethodInfo method : interfaceInfo.methods()) {\n                String getterName = method.name();\n                String propertyName = JavaBeanUtil.getPropertyNameFromGetter(getterName);\n\n                Type returnType = method.returnType();\n                if (returnType.kind() == Type.Kind.VOID) {\n                    throw new IllegalArgumentException(\"Method \" + method.name() + \" of interface \" + interfaceName\n                            + \" is not a getter method since it returns void\");\n                }\n                DotName fieldTypeName = returnType.name();\n\n                FieldDesc field = implClassCreator.field(propertyName, ifc -> {\n                    ifc.setType(GenerationUtil.toClassDesc(fieldTypeName.toString()));\n                });\n\n                // create getter (based on the interface)\n                MethodTypeDesc getterMtd = GenerationUtil.toMethodTypeDesc(returnType.name().toString());\n                implClassCreator.method(getterName, mc -> {\n                    mc.setType(getterMtd);\n                    mc.public_();\n                    mc.body(bc -> {\n                        bc.return_(bc.get(mc.this_().field(field)));\n                    });\n                });\n","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/generate/DerivedMethodsAdder.java#L423-L459","documentation":"When a derived query returns a non-entity interface projection, Quarkus's spring-data-jpa extension generates an implementation class of that interface in generateCustomResultTypes. Every method in the interface is treated as a JavaBean getter (getX/isX mapped to a property), so a getter-shaped method returning void cannot be backed by any entity field and the build fails with this IllegalArgumentException.","triggerScenarios":"Declaring a projection interface containing e.g. void printName(); or any method whose name parses as a getter (JavaBeanUtil.getPropertyNameFromGetter succeeds) but whose return type kind is VOID — this also covers methods with parameters or abstract defaults that return void.","commonSituations":"Adding helper/formatting methods to a projection interface expecting a default method or DTO behavior; accidentally leaving a stub method with no return type; misunderstanding that projection interfaces must contain only pure getters.","solutions":["Remove the void method from the projection interface — it must contain only getters","Give the method a proper return type matching an entity property (e.g. String getName())","Move formatting/helper logic into the consuming service or a default method with a non-void, computed result if supported"],"exampleFix":"// before\ninterface PersonView {\n    String getName();\n    void printName();\n}\n\n// after\ninterface PersonView {\n    String getName();\n}","handlingStrategy":"validation","validationCode":"// Ensure projection interfaces contain only non-void getters\nstatic void checkProjection(Class<?> ifc) {\n    for (Method m : ifc.getDeclaredMethods()) {\n        if (m.getReturnType() == void.class)\n            throw new IllegalStateException(m.getName() + \" in \" + ifc.getName() + \" must not return void\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep projection interfaces limited to pure getters","Move formatting logic out of projections into services","Review projection interfaces whenever entity fields change"],"tags":["spring-data","jpa","quarkus","projection","build-time"],"backgroundTag":"invalid-projection-getter","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"}