{"record":{"id":"af9596f8d3931df0","repo":"quarkusio/quarkus","slug":"disposer-method-must-not-be-annotated-produces-a","errorCode":null,"errorMessage":"Disposer method must not be annotated @Produces (alternatively, producer method must not have a @Disposes parameter): ","messagePattern":"Disposer method must not be annotated @Produces \\(alternatively, producer method must not have a @Disposes parameter\\): ","errorType":"validation","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java","lineNumber":409,"sourceCode":"                // injections are discovered bottom-up to easily skip overriden methods,\n                // but they need to be performed top-down per the AtInject specification\n                superInjections.addAll(injections);\n                injections = superInjections;\n            }\n        }\n\n        return injections;\n    }\n\n    static Injection forDisposer(MethodInfo disposerMethod, ClassInfo beanClass, BeanDeployment beanDeployment,\n            InjectionPointModifier transformer) {\n        if (beanDeployment.hasAnnotation(disposerMethod, DotNames.INJECT)) {\n            throw new DefinitionException(\"Disposer method must not be annotated @Inject \"\n                    + \"(alternatively, initializer method must not have a @Disposes parameter): \"\n                    + disposerMethod);\n        }\n        if (beanDeployment.hasAnnotation(disposerMethod, DotNames.PRODUCES)) {\n            throw new DefinitionException(\"Disposer method must not be annotated @Produces \"\n                    + \"(alternatively, producer method must not have a @Disposes parameter): \"\n                    + disposerMethod);\n        }\n        if (Annotations.hasParameterAnnotation(beanDeployment, disposerMethod, DotNames.OBSERVES)) {\n            throw new DefinitionException(\"Disposer method must not have an @Observes parameter \"\n                    + \"(alternatively, observer method must not have a @Disposes parameter): \"\n                    + disposerMethod);\n        }\n        if (Annotations.hasParameterAnnotation(beanDeployment, disposerMethod, DotNames.OBSERVES_ASYNC)) {\n            throw new DefinitionException(\"Disposer method must not have an @ObservesAsync parameter \"\n                    + \"(alternatively, async observer method must not have a @Disposes parameter): \"\n                    + disposerMethod);\n        }\n        if (Annotations.getParameterAnnotations(beanDeployment, disposerMethod)\n                .stream()\n                .filter(it -> DotNames.DISPOSES.equals(it.name()))\n                .count() > 1) {\n            throw new DefinitionException(\"Disposer method must not have more than 1 @Disposes parameter: \"","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java#L391-L427","documentation":"Build-time CDI definition error from Injection.forDisposer: the disposer method (one having a @Disposes parameter) is also annotated @Produces, making it simultaneously a producer method and a disposer — an illegal combination. The method is appended to the message text.","triggerScenarios":"Annotating a method that has a @Disposes parameter with @Produces; detected in Injection.forDisposer at build time.","commonSituations":"Trying to produce a bean and dispose it in the same method; accidentally leaving @Produces on a method when adding a @Disposes parameter.","solutions":["Remove @Produces from the disposer method","Split into a @Produces method plus a separate disposer method with the @Disposes parameter","If the method was meant to be a producer, remove the @Disposes parameter"],"exampleFix":"// before\n@Produces\nvoid handle(@Disposes Widget w) {}\n// after\n@Produces\nWidget produce() { return new Widget(); }\nvoid dispose(@Disposes Widget w) {}","handlingStrategy":"validation","validationCode":"for (Method m : MyClass.class.getDeclaredMethods()) {\n    boolean hasDisposes = java.util.Arrays.stream(m.getParameterAnnotations())\n        .flatMap(java.util.Arrays::stream).anyMatch(a -> a.annotationType().getSimpleName().equals(\"Disposes\"));\n    if (hasDisposes && m.isAnnotationPresent(Produces.class)) {\n        throw new IllegalStateException(\"@Produces disposer: \" + m);\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["A producer and its disposer must be separate methods","Remove @Produces when adding a @Disposes parameter to a method"],"tags":["cdi","arc","disposer","producer"],"backgroundTag":"disposer-method-role-conflict","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"}