{"record":{"id":"b0983a47963df2aa","repo":"quarkusio/quarkus","slug":"initializer-method-must-not-have-a-disposes-param","errorCode":null,"errorMessage":"Initializer method must not have a @Disposes parameter (alternatively, disposer method must not be annotated @Inject): ","messagePattern":"Initializer method must not have a @Disposes parameter \\(alternatively, disposer 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":256,"sourceCode":"                        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                }\n            }\n            validateInjections(injections, beanType);\n            return injections;\n        } else if (Kind.METHOD.equals(beanTarget.kind())) {\n            MethodInfo producerMethod = beanTarget.asMethod();","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java#L238-L274","documentation":"ArC throws this DefinitionException when an initializer (@Inject) method has a parameter annotated @Disposes — or equivalently when a disposer method is annotated @Inject. @Disposes parameters belong exclusively on disposer methods paired with a @Produces method; initializer methods may only declare plain injection points.","triggerScenarios":"An initializer method like @Inject void init(Foo f) where parameter f carries @Disposes; detected via Annotations.hasParameterAnnotation(initializerMethod, DotNames.DISPOSES) in forBean.","commonSituations":"Merging a disposer into an @Inject setter; auto-completing annotations so @Disposes lands on an init method; confusion about where disposal callbacks belong in ArC.","solutions":["Remove @Disposes from the initializer method parameter","Create a proper disposer method paired with the @Produces method that creates the object: void dispose(@Disposes Foo f)","If lifecycle cleanup is needed on the bean, use @PreDestroy instead","Rebuild; the check runs during Quarkus augmentation"],"exampleFix":"// before\n@Inject\nvoid init(@Disposes Resource r) { ... }\n\n// after\n@Inject\nvoid init(Resource r) { ... }\n\nvoid dispose(@Disposes Resource r) { r.close(); } // paired with @Produces","handlingStrategy":"validation","validationCode":"void checkInitializer(Method m) {\n    if (!m.isAnnotationPresent(jakarta.inject.Inject.class)) return;\n    for (var p : m.getParameters()) {\n        if (p.isAnnotationPresent(jakarta.enterprise.inject.Disposes.class)) {\n            throw new IllegalStateException(\"@Disposes on initializer param: \" + m);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["@Disposes parameters belong only on disposer methods paired with @Produces","Use @PreDestroy for bean lifecycle cleanup instead of initializers","Keep initializers limited to plain injection parameters","Search codebase for '@Disposes' during refactors to verify placement"],"tags":["cdi","arc","disposes","initializer","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"}