quarkusio/quarkus · error · DefinitionException
Producer method must not have an @ObservesAsync parameter (a
Error message
Producer method must not have an @ObservesAsync parameter (alternatively, async observer method must not be annotated @Produces):
What it means
ArC rejects a producer method (@Produces) that declares an @ObservesAsync parameter. A method cannot simultaneously produce a bean and act as an asynchronous CDI observer; the spec forbids this dual role. Remove one of the two roles and split the logic into separate methods.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:292
MethodInfo producerMethod = beanTarget.asMethod();
if (beanDeployment.hasAnnotation(producerMethod, DotNames.INJECT)) {
throw new DefinitionException("Producer method must not be annotated @Inject "
+ "(alternatively, initializer method must not be annotated @Produces): "
+ producerMethod);
}
if (Annotations.hasParameterAnnotation(beanDeployment, producerMethod, DotNames.DISPOSES)) {
throw new DefinitionException("Producer method must not have a @Disposes parameter "
+ "(alternatively, disposer method must not be annotated @Produces): "
+ producerMethod);
}
if (Annotations.hasParameterAnnotation(beanDeployment, producerMethod, DotNames.OBSERVES)) {
throw new DefinitionException("Producer method must not have an @Observes parameter "
+ "(alternatively, observer method must not be annotated @Produces): "
+ producerMethod);
}
if (Annotations.hasParameterAnnotation(beanDeployment, producerMethod, DotNames.OBSERVES_ASYNC)) {
throw new DefinitionException("Producer method must not have an @ObservesAsync parameter "
+ "(alternatively, async observer method must not be annotated @Produces): "
+ producerMethod);
}
if (producerMethod.parameterTypes().isEmpty()) {
return Collections.emptyList();
}
// All parameters are injection points
List<Injection> injections = Collections.singletonList(new Injection(producerMethod,
InjectionPointInfo.fromMethod(producerMethod, declaringBean.getImplClazz(), beanDeployment, transformer)));
validateInjections(injections, beanType);
return injections;
}
throw new IllegalArgumentException("Unsupported annotation target");
}
static enum BeanType {
MANAGED_BEAN,View on GitHub (pinned to e1c734241f)
Solutions
- Remove the @ObservesAsync parameter from the @Produces method and move the payload into a normal parameter or field
- Split into two methods: one @Produces method for the bean, one separate @ObservesAsync observer method
- If the intent was an observer, drop @Produces from the method
Example fix
// before
@Produces
void onEvent(@ObservesAsync Msg msg) {}
// after
void onEvent(@ObservesAsync Msg msg) {}
@Produces
String produce() { return "x"; } Defensive patterns
Strategy: validation
Validate before calling
boolean bad = java.lang.reflect.Modifier.isStatic(0);
for (Method m : MyClass.class.getDeclaredMethods()) {
if (m.isAnnotationPresent(Produces.class) &&
java.util.Arrays.stream(m.getParameterAnnotations()).flatMap(java.util.Arrays::stream)
.anyMatch(a -> a.annotationType().getSimpleName().equals("ObservesAsync"))) {
throw new IllegalStateException("Producer with @ObservesAsync param: " + m);
}
} Prevention
- Keep producer methods free of any @Observes/@ObservesAsync parameters
- Separate producer and observer concerns into distinct methods
- Run a Quarkus dev-mode build early; ArC reports this at deployment time
When it happens
Trigger: Declaring a method annotated @Produces that has a parameter annotated @ObservesAsync; detected during bean discovery at build time by Injection.forBean.
Common situations: Copy-pasting observer logic into a producer method; refactoring an observer method to also expose its result as a bean; misunderstanding that producer methods may only have @Disposes-style special parameters, not observer parameters.
Related errors
- Disposer method must not have an @Observes parameter (altern
- Disposer method must not have an @ObservesAsync parameter (a
- Quarkus does not support CDI Full @Specializes annotation; t
- IllegalStateException wrapping ClassNotFoundException for ge
- Unable to derive the logger name at ${injectionPoint}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ac383b8c4ae9f1e2.
Report an issue: GitHub.