quarkusio/quarkus · error · DefinitionException
Disposer method must not have an @ObservesAsync parameter (a
Error message
Disposer method must not have an @ObservesAsync parameter (alternatively, async observer method must not have a @Disposes parameter):
What it means
Build-time CDI definition error from Injection.forDisposer: the method declares more than one parameter annotated @Disposes. Exactly one disposed parameter is allowed per disposer method; the method signature follows the message.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:419
static Injection forDisposer(MethodInfo disposerMethod, ClassInfo beanClass, BeanDeployment beanDeployment,
InjectionPointModifier transformer) {
if (beanDeployment.hasAnnotation(disposerMethod, DotNames.INJECT)) {
throw new DefinitionException("Disposer method must not be annotated @Inject "
+ "(alternatively, initializer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (beanDeployment.hasAnnotation(disposerMethod, DotNames.PRODUCES)) {
throw new DefinitionException("Disposer method must not be annotated @Produces "
+ "(alternatively, producer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (Annotations.hasParameterAnnotation(beanDeployment, disposerMethod, DotNames.OBSERVES)) {
throw new DefinitionException("Disposer method must not have an @Observes parameter "
+ "(alternatively, observer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (Annotations.hasParameterAnnotation(beanDeployment, disposerMethod, DotNames.OBSERVES_ASYNC)) {
throw new DefinitionException("Disposer method must not have an @ObservesAsync parameter "
+ "(alternatively, async observer method must not have a @Disposes parameter): "
+ disposerMethod);
}
if (Annotations.getParameterAnnotations(beanDeployment, disposerMethod)
.stream()
.filter(it -> DotNames.DISPOSES.equals(it.name()))
.count() > 1) {
throw new DefinitionException("Disposer method must not have more than 1 @Disposes parameter: "
+ disposerMethod);
}
Injection injection = new Injection(disposerMethod,
InjectionPointInfo.fromMethod(disposerMethod, beanClass, beanDeployment,
(annotations, position) -> annotations.stream().anyMatch(a -> a.name().equals(DotNames.DISPOSES)),
transformer));
injection.injectionPoints.forEach(ipi -> validateInjections(ipi, BeanType.MANAGED_BEAN));
return injection;
}View on GitHub (pinned to e1c734241f)
Solutions
- Split into two methods: one @ObservesAsync observer, one disposer with @Disposes
- Remove the @ObservesAsync parameter from the disposer
- Remove the @Disposes parameter if the method was meant to be an async observer
Example fix
// before
void both(@ObservesAsync Ev e, @Disposes Widget w) {}
// after
void observe(@ObservesAsync Ev e) {}
void dispose(@Disposes Widget w) {} Defensive patterns
Strategy: validation
Validate before calling
for (Method m : MyClass.class.getDeclaredMethods()) {
var names = java.util.Arrays.stream(m.getParameterAnnotations()).flatMap(java.util.Arrays::stream)
.map(a -> a.annotationType().getSimpleName()).collect(java.util.stream.Collectors.toSet());
if (names.contains("Disposes") && names.contains("ObservesAsync")) throw new IllegalStateException("Async observer+disposer: " + m);
} Prevention
- Keep @ObservesAsync handlers free of @Disposes parameters
- Split async event consumption and disposal into separate methods
When it happens
Trigger: Declaring a method with both a @Disposes parameter and an @ObservesAsync parameter; detected in Injection.forDisposer.
Common situations: Combining async event handling with disposal in one method; refactoring observers into disposers or vice versa.
Related errors
- Disposer method must not have an @Observes parameter (altern
- Decorator declares an async observer method: ${decoratorClas
- Multiple disposed parameters found for ${disposerMethod}
- Producer method must not have an @ObservesAsync parameter (a
- Disposer method must not be annotated @Inject (alternatively
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/453b8cc39480beac.
Report an issue: GitHub.