{"record":{"id":"d7f7fcebf4c8acea","repo":"quarkusio/quarkus","slug":"exactlyonce-on-method-methodname-requires-at-l","errorCode":null,"errorMessage":"@ExactlyOnce on method ${methodName} requires at least one parameter","messagePattern":"@ExactlyOnce on method (.+?) requires at least one parameter","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/smallrye-reactive-messaging-kafka/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/deployment/SmallRyeReactiveMessagingKafkaProcessor.java","lineNumber":155,"sourceCode":"        DefaultSerdeDiscoveryState discoveryState = new DefaultSerdeDiscoveryState(combinedIndex.getIndex());\n\n        for (AnnotationInstance annotation : combinedIndex.getIndex().getAnnotations(DotNames.EXACTLY_ONCE)) {\n            if (annotation.target().kind() != AnnotationTarget.Kind.METHOD) {\n                continue;\n            }\n            MethodInfo method = annotation.target().asMethod();\n            String methodName = method.declaringClass().name() + \"#\" + method.name();\n\n            AnnotationInstance incoming = method.annotation(DotNames.INCOMING);\n            AnnotationInstance outgoing = method.annotation(DotNames.OUTGOING);\n\n            if (incoming == null || outgoing == null) {\n                throw new IllegalArgumentException(\n                        \"@ExactlyOnce on method \" + methodName + \" requires both @Incoming and @Outgoing annotations\");\n            }\n\n            if (method.parametersCount() == 0) {\n                throw new IllegalArgumentException(\n                        \"@ExactlyOnce on method \" + methodName + \" requires at least one parameter\");\n            }\n\n            for (Type paramType : method.parameterTypes()) {\n                if (paramType.name().equals(DotNames.MESSAGE)) {\n                    throw new IllegalArgumentException(\n                            \"@ExactlyOnce on method \" + methodName\n                                    + \" does not support Message parameters, use payload types instead\");\n                }\n            }\n\n            if (method.returnType().name().equals(DotNames.VOID)\n                    || method.returnType().name().equals(VOID_BOXED)) {\n                throw new IllegalArgumentException(\n                        \"@ExactlyOnce on method \" + methodName\n                                + \" must return a value to produce to the outgoing channel\");\n            }\n","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/smallrye-reactive-messaging-kafka/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/deployment/SmallRyeReactiveMessagingKafkaProcessor.java#L137-L173","documentation":"An @ExactlyOnce Kafka processing method must accept at least one parameter, because exactly-once processing needs the incoming payload/Message to forward to the @Outgoing stream. A zero-parameter method fails the deployment build.","triggerScenarios":"@ExactlyOnce on a method with no parameters (e.g. a supplier-style method alongside @Incoming+@Outgoing).","commonSituations":"Converting a @Pollable/supplier method to @ExactlyOnce; cleaning up 'unused' parameters that were actually required.","solutions":["Add the incoming payload parameter (e.g. String m or the specific payload type).","Use a Message<T> payload? No — Message parameters are rejected; use raw payload type instead (see related error).","Remove @ExactlyOnce if the method is meant to be a pure producer."],"exampleFix":"// before\n@Incoming(\"in\") @Outgoing(\"out\") @ExactlyOnce\nString process() { return \"x\"; }\n// after\n@Incoming(\"in\") @Outgoing(\"out\") @ExactlyOnce\nString process(String payload) { return transform(payload); }","handlingStrategy":"validation","validationCode":"fun validateExactlyOnceSignature(paramCount: Int, hasExactlyOnce: Boolean): Boolean =\n    !hasExactlyOnce || paramCount >= 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always consume the incoming payload parameter in @ExactlyOnce methods.","Do not strip 'unused' parameters from processing methods.","Rely on IDE annotation-inspection to flag empty-signature processors."],"tags":["kafka","exactly-once","signature","quarkus","deployment"],"backgroundTag":"exactly-once-annotation-misuse","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"}