{"record":{"id":"f166f4dd6e293150","repo":"quarkusio/quarkus","slug":"disposer-method-must-not-have-an-observes-paramet","errorCode":null,"errorMessage":"Disposer method must not have an @Observes parameter (alternatively, observer method must not have a @Disposes parameter): ","messagePattern":"Disposer method must not have an @Observes parameter \\(alternatively, observer 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":414,"sourceCode":"        }\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: \"\n                    + disposerMethod);\n        }\n\n        Injection injection = new Injection(disposerMethod,\n                InjectionPointInfo.fromMethod(disposerMethod, beanClass, beanDeployment,","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java#L396-L432","documentation":"Build-time CDI definition error from Injection.forDisposer: the method with a @Disposes parameter also has an @Observes parameter, so it would be both an observer and a disposer, which the CDI spec disallows. The offending method appears after the colon.","triggerScenarios":"Declaring a method with both a @Disposes parameter and an @Observes parameter; detected in Injection.forDisposer.","commonSituations":"Mixing lifecycle roles on a single method after refactoring; copy-pasting observer signatures onto disposers.","solutions":["Split into two methods: one observer with @Observes, one disposer with @Disposes","Remove the @Observes parameter from the disposer","Remove the @Disposes parameter if the method was meant to be an observer"],"exampleFix":"// before\nvoid both(@Observes Ev e, @Disposes Widget w) {}\n// after\nvoid observe(@Observes Ev e) {}\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    boolean hasObserves = java.util.Arrays.stream(m.getParameterAnnotations())\n        .flatMap(java.util.Arrays::stream).anyMatch(a -> a.annotationType().getSimpleName().equals(\"Observes\"));\n    if (hasDisposes && hasObserves) throw new IllegalStateException(\"Observer+disposer: \" + m);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One role per method: observer or disposer, never both","Audit methods with multiple special parameters (@Observes, @Disposes, @Produces)"],"tags":["cdi","arc","disposer","observer"],"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"}