quarkusio/quarkus · error · DefinitionException

Bean constructor must not have an @ObservesAsync parameter:

Error message

Bean constructor must not have an @ObservesAsync parameter: 

What it means

ArC throws this DefinitionException at build time when a bean constructor has a parameter annotated with @ObservesAsync. Async observer parameters are only valid on observer methods, never on constructors. Injection.forBean checks constructor parameters against OBSERVES_ASYNC and rejects the bean definition.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:238

            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): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }
                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.DISPOSES)) {
                    throw new DefinitionException("Initializer method must not have a @Disposes parameter "

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove @ObservesAsync from the constructor parameter
  2. Move async event handling into a dedicated method: void onEvent(@ObservesAsync MyEvent e) { ... }
  3. Use CompletionStage/Uni-based handling inside an observer method instead of the constructor
  4. Rebuild after fixing; error occurs during augmentation

Example fix

// before
@Inject
MyBean(@ObservesAsync TaskEvent e) { ... }

// after
@Inject
MyBean() { }

void onTask(@ObservesAsync TaskEvent 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.ObservesAsync.class)) {
            throw new IllegalStateException("@ObservesAsync on constructor param: " + ctor);
        }
    }
}

Prevention

When it happens

Trigger: Annotating a bean constructor parameter with @jakarta.enterprise.event.ObservesAsync, detected while ArC iterates parameter annotations of inject constructors in forBean.

Common situations: Confusing @ObservesAsync with @Observes when wiring async event handling into bean creation; refactoring an async observer method into a constructor; copy-paste from a listener class.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/16d31a35f436b3df. Report an issue: GitHub.