quarkusio/quarkus · error · DefinitionException

Initializer method must not have a @Disposes parameter (alte

Error message

Initializer method must not have a @Disposes parameter (alternatively, disposer method must not be annotated @Inject): 

What it means

ArC throws this DefinitionException when an initializer (@Inject) method has a parameter annotated @Disposes — or equivalently when a disposer method is annotated @Inject. @Disposes parameters belong exclusively on disposer methods paired with a @Produces method; initializer methods may only declare plain injection points.

Source

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

                        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 "
                            + "(alternatively, disposer method must not be annotated @Inject): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }
                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.OBSERVES)) {
                    throw new DefinitionException("Initializer method must not have an @Observes parameter "
                            + "(alternatively, observer method must not be annotated @Inject): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }
                if (Annotations.hasParameterAnnotation(beanDeployment, initializerMethod, DotNames.OBSERVES_ASYNC)) {
                    throw new DefinitionException("Initializer method must not have an @ObservesAsync parameter "
                            + "(alternatively, async observer method must not be annotated @Inject): "
                            + beanTarget.asClass() + "." + initializerMethod.name());
                }
            }
            validateInjections(injections, beanType);
            return injections;
        } else if (Kind.METHOD.equals(beanTarget.kind())) {
            MethodInfo producerMethod = beanTarget.asMethod();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove @Disposes from the initializer method parameter
  2. Create a proper disposer method paired with the @Produces method that creates the object: void dispose(@Disposes Foo f)
  3. If lifecycle cleanup is needed on the bean, use @PreDestroy instead
  4. Rebuild; the check runs during Quarkus augmentation

Example fix

// before
@Inject
void init(@Disposes Resource r) { ... }

// after
@Inject
void init(Resource r) { ... }

void dispose(@Disposes Resource r) { r.close(); } // paired with @Produces
Defensive patterns

Strategy: validation

Validate before calling

void checkInitializer(Method m) {
    if (!m.isAnnotationPresent(jakarta.inject.Inject.class)) return;
    for (var p : m.getParameters()) {
        if (p.isAnnotationPresent(jakarta.enterprise.inject.Disposes.class)) {
            throw new IllegalStateException("@Disposes on initializer param: " + m);
        }
    }
}

Prevention

When it happens

Trigger: An initializer method like @Inject void init(Foo f) where parameter f carries @Disposes; detected via Annotations.hasParameterAnnotation(initializerMethod, DotNames.DISPOSES) in forBean.

Common situations: Merging a disposer into an @Inject setter; auto-completing annotations so @Disposes lands on an init method; confusion about where disposal callbacks belong in ArC.

Related errors


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