{"record":{"id":"16d31a35f436b3df","repo":"quarkusio/quarkus","slug":"bean-constructor-must-not-have-an-observesasync-p","errorCode":null,"errorMessage":"Bean constructor must not have an @ObservesAsync parameter: ","messagePattern":"Bean constructor must not have an @ObservesAsync parameter: ","errorType":"validation","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java","lineNumber":238,"sourceCode":"            if (injectConstructors.size() > 1) {\n                throw new DefinitionException(\n                        \"Multiple @Inject constructors found on \" + beanTarget.asClass().name() + \":\\n\"\n                                + injectConstructors.stream().map(Object::toString).collect(Collectors.joining(\"\\n\")));\n            }\n            for (AnnotationTarget injectConstructor : injectConstructors) {\n                Set<AnnotationInstance> parameterAnnotations = Annotations.getParameterAnnotations(beanDeployment,\n                        injectConstructor.asMethod());\n                for (AnnotationInstance annotation : parameterAnnotations) {\n                    if (DotNames.DISPOSES.equals(annotation.name())) {\n                        throw new DefinitionException(\n                                \"Bean constructor must not have a @Disposes parameter: \" + injectConstructor);\n                    }\n                    if (DotNames.OBSERVES.equals(annotation.name())) {\n                        throw new DefinitionException(\n                                \"Bean constructor must not have an @Observes parameter: \" + injectConstructor);\n                    }\n                    if (DotNames.OBSERVES_ASYNC.equals(annotation.name())) {\n                        throw new DefinitionException(\n                                \"Bean constructor must not have an @ObservesAsync parameter: \" + injectConstructor);\n                    }\n                }\n            }\n\n            Set<MethodInfo> initializerMethods = injections.stream()\n                    .filter(it -> it.isMethod() && !it.isConstructor())\n                    .map(Injection::getTarget)\n                    .map(AnnotationTarget::asMethod)\n                    .collect(Collectors.toSet());\n            for (MethodInfo initializerMethod : initializerMethods) {\n                if (beanDeployment.hasAnnotation(initializerMethod, DotNames.PRODUCES)) {\n                    throw new DefinitionException(\"Initializer method must not be annotated @Produces \"\n                            + \"(alternatively, producer method must not be annotated @Inject): \"\n                            + beanTarget.asClass() + \".\" + initializerMethod.name());\n                }\n                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.DISPOSES)) {\n                    throw new DefinitionException(\"Initializer method must not have a @Disposes parameter \"","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java#L220-L256","documentation":"ArC throws this DefinitionException at build time when a bean constructor has a parameter annotated with @ObservesAsync. Async observer parameters are only valid on observer methods, never on constructors. Injection.forBean checks constructor parameters against OBSERVES_ASYNC and rejects the bean definition.","triggerScenarios":"Annotating a bean constructor parameter with @jakarta.enterprise.event.ObservesAsync, detected while ArC iterates parameter annotations of inject constructors in forBean.","commonSituations":"Confusing @ObservesAsync with @Observes when wiring async event handling into bean creation; refactoring an async observer method into a constructor; copy-paste from a listener class.","solutions":["Remove @ObservesAsync from the constructor parameter","Move async event handling into a dedicated method: void onEvent(@ObservesAsync MyEvent e) { ... }","Use CompletionStage/Uni-based handling inside an observer method instead of the constructor","Rebuild after fixing; error occurs during augmentation"],"exampleFix":"// before\n@Inject\nMyBean(@ObservesAsync TaskEvent e) { ... }\n\n// after\n@Inject\nMyBean() { }\n\nvoid onTask(@ObservesAsync TaskEvent e) { ... }","handlingStrategy":"validation","validationCode":"void checkConstructor(Method ctor) throws Exception {\n    for (var p : ctor.getParameters()) {\n        if (p.isAnnotationPresent(jakarta.enterprise.event.ObservesAsync.class)) {\n            throw new IllegalStateException(\"@ObservesAsync on constructor param: \" + ctor);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use @ObservesAsync only on dedicated observer methods","Remember async observers return void/CompletionStage, never appear on constructors","Keep constructor signatures free of event annotations","Compile early and often — ArC catches these during augmentation"],"tags":["cdi","arc","observes-async","bean-definition","build-time"],"backgroundTag":"cdi-bean-definition-invalid","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}