quarkusio/quarkus · error · DefinitionException
Bean constructor must not have an @Observes parameter:
Error message
Bean constructor must not have an @Observes parameter:
What it means
ArC throws this DefinitionException at build time when a bean constructor declares a parameter annotated with @Observes. Observer method parameters belong only on @Observes methods; constructors may only declare injection points. The CDI spec forbids observer annotations on bean constructors, and Injection.forBean enforces this while scanning the constructor's parameter annotations.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:234
transformer, false, new HashSet<>());
Set<AnnotationTarget> injectConstructors = injections.stream().filter(Injection::isConstructor)
.map(Injection::getTarget).collect(Collectors.toSet());
if (injectConstructors.size() > 1) {
throw new DefinitionException(
"Multiple @Inject constructors found on " + beanTarget.asClass().name() + ":\n"
+ injectConstructors.stream().map(Object::toString).collect(Collectors.joining("\n")));
}
for (AnnotationTarget injectConstructor : injectConstructors) {
Set<AnnotationInstance> parameterAnnotations = Annotations.getParameterAnnotations(beanDeployment,
injectConstructor.asMethod());
for (AnnotationInstance annotation : parameterAnnotations) {
if (DotNames.DISPOSES.equals(annotation.name())) {
throw new DefinitionException(
"Bean constructor must not have a @Disposes parameter: " + injectConstructor);
}
if (DotNames.OBSERVES.equals(annotation.name())) {
throw new DefinitionException(
"Bean constructor must not have an @Observes parameter: " + injectConstructor);
}
if (DotNames.OBSERVES_ASYNC.equals(annotation.name())) {
throw new DefinitionException(
"Bean constructor must not have an @ObservesAsync parameter: " + injectConstructor);
}
}
}
Set<MethodInfo> initializerMethods = injections.stream()
.filter(it -> it.isMethod() && !it.isConstructor())
.map(Injection::getTarget)
.map(AnnotationTarget::asMethod)
.collect(Collectors.toSet());
for (MethodInfo initializerMethod : initializerMethods) {
if (beanDeployment.hasAnnotation(initializerMethod, DotNames.PRODUCES)) {
throw new DefinitionException("Initializer method must not be annotated @Produces "
+ "(alternatively, producer method must not be annotated @Inject): "View on GitHub (pinned to e1c734241f)
Solutions
- Remove @Observes from the constructor parameter
- Add a dedicated observer method: void onEvent(@Observes MyEvent e) { ... } inside the bean
- Inject the event payload type as a normal injection point if you actually need it in the constructor
- Rebuild; the exception is raised during Quarkus augmentation, not at runtime
Example fix
// before
@Inject
MyBean(@Observes StartupEvent e) { ... }
// after
@Inject
MyBean() { }
void onStart(@Observes StartupEvent e) { ... } Defensive patterns
Strategy: validation
Validate before calling
void checkConstructor(Method ctor) throws Exception {
for (var p : ctor.getParameters()) {
if (p.isAnnotationPresent(jakarta.enterprise.event.Observes.class)) {
throw new IllegalStateException("@Observes on constructor param: " + ctor);
}
}
} Prevention
- Put @Observes only on void observer methods with one event parameter
- Handle StartupEvent via a dedicated method, never the constructor
- Keep bean constructors limited to plain injection parameters
- Review refactors that move observer code — event annotations must move to methods, not constructors
When it happens
Trigger: Annotating a parameter of a bean's @Inject constructor with @jakarta.enterprise.event.Observes (or @Observes(priority)), so ArC detects DotNames.OBSERVES on the constructor while processing inject constructors in forBean.
Common situations: Developer intends the bean to receive events and mistakenly puts @Observes on the constructor parameter; refactoring an observer method into a constructor; auto-generated constructor stubs that kept an @Observes parameter.
Related errors
- Initializer method must not have an @Observes parameter (alt
- Producer method must not have an @Observes parameter (altern
- Bean constructor must not have a @Disposes parameter:
- Bean constructor must not have an @ObservesAsync parameter:
- Initializer method must not be annotated @Produces (alternat
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/644c6c26a8d2f74c.
Report an issue: GitHub.