{"record":{"id":"7d0fd7ddca88b155","repo":"quarkusio/quarkus","slug":"initializer-method-must-not-be-annotated-produces","errorCode":null,"errorMessage":"Initializer method must not be annotated @Produces (alternatively, producer method must not be annotated @Inject): ","messagePattern":"Initializer method must not be annotated @Produces \\(alternatively, producer method must not be annotated @Inject\\): ","errorType":"validation","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java","lineNumber":251,"sourceCode":"                    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 \"\n                            + \"(alternatively, disposer method must not be annotated @Inject): \"\n                            + beanTarget.asClass() + \".\" + initializerMethod.name());\n                }\n                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.OBSERVES)) {\n                    throw new DefinitionException(\"Initializer method must not have an @Observes parameter \"\n                            + \"(alternatively, observer method must not be annotated @Inject): \"\n                            + beanTarget.asClass() + \".\" + initializerMethod.name());\n                }\n                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.OBSERVES_ASYNC)) {\n                    throw new DefinitionException(\"Initializer method must not have an @ObservesAsync parameter \"\n                            + \"(alternatively, async observer method must not be annotated @Inject): \"\n                            + beanTarget.asClass() + \".\" + initializerMethod.name());\n                }","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java#L233-L269","documentation":"ArC throws this DefinitionException when a method annotated @Inject (an initializer/injection method) is also annotated @Produces, or equivalently when a producer method is annotated @Inject. A method cannot simultaneously be an initializer and a producer — the CDI spec forbids the combination and forBean validates initializer methods for this conflict.","triggerScenarios":"Annotating a method with both @Inject and @Produces in a bean class; detected when ArC checks initializerMethods (non-constructor injection methods) for DotNames.PRODUCES in forBean.","commonSituations":"Adding @Produces to an existing @Inject setter; IDE quick-fix adding both annotations; misunderstanding that @Inject+@Produces makes a 'producing initializer'; migration between CDI versions where such combinations were accidentally tolerated elsewhere.","solutions":["Decide the method's role: if it produces a bean, remove @Inject and keep @Produces","If it is an initializer (setter injection), remove @Produces and keep @Inject","If field injection suffices, use @Inject on a field and a separate @Produces method for the produced type","Rebuild; validation happens at Quarkus augmentation time"],"exampleFix":"// before\n@Inject\n@Produces\n@ApplicationScoped\nService service() { return new Service(); }\n\n// after\n@Produces\n@ApplicationScoped\nService service() { return new Service(); }","handlingStrategy":"validation","validationCode":"void checkMethod(Method m) {\n    boolean inject = m.isAnnotationPresent(jakarta.inject.Inject.class);\n    boolean produces = m.isAnnotationPresent(jakarta.enterprise.inject.Produces.class);\n    if (inject && produces) {\n        throw new IllegalStateException(\"@Inject + @Produces on: \" + m);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One role per method: either initializer (@Inject) or producer (@Produces), never both","Rely on field injection for initializers and dedicated methods for producers","Beware IDE quick-fixes that add both annotations","Check annotation pairs after merging code from branches"],"tags":["cdi","arc","produces","inject","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-14T00:17:10.932Z"}