quarkusio/quarkus · error · DefinitionException

The decorator ${decoratorClass} has multiple @Delegate injec

Error message

The decorator ${decoratorClass} has multiple @Delegate injection points: ${delegateInjectionPoints}

What it means

CDI forbids more than one @Delegate injection point per decorator because the delegate target must be unambiguous. Arc raises a DefinitionException listing all delegate injection points found on the decorator class.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Decorators.java:54

     */
    static DecoratorInfo createDecorator(ClassInfo decoratorClass, BeanDeployment beanDeployment,
            InjectionPointModifier transformer) {

        // Find the delegate injection point
        List<InjectionPointInfo> delegateInjectionPoints = new ArrayList<>();
        List<Injection> injections = Injection.forBean(decoratorClass, null, beanDeployment, transformer,
                Injection.BeanType.DECORATOR);
        for (Injection injection : injections) {
            for (InjectionPointInfo injectionPoint : injection.injectionPoints) {
                if (injectionPoint.isDelegate()) {
                    delegateInjectionPoints.add(injectionPoint);
                }
            }
        }
        if (delegateInjectionPoints.isEmpty()) {
            throw new DefinitionException("The decorator " + decoratorClass + " has no @Delegate injection point");
        } else if (delegateInjectionPoints.size() > 1) {
            throw new DefinitionException(
                    "The decorator " + decoratorClass + " has multiple @Delegate injection points: " + delegateInjectionPoints);
        }

        InjectionPointInfo delegateInjectionPoint = delegateInjectionPoints.get(0);

        Integer priority = null;
        for (AnnotationInstance annotation : beanDeployment.getAnnotations(decoratorClass)) {
            if (annotation.name().equals(DotNames.PRIORITY)) {
                priority = annotation.value().asInt();
            }
            ScopeInfo scopeAnnotation = beanDeployment.getScope(annotation.name());
            if (scopeAnnotation != null && !BuiltinScope.DEPENDENT.is(scopeAnnotation)) {
                throw new DefinitionException(
                        "A decorator must be @Dependent but " + decoratorClass + " declares " + scopeAnnotation.getDotName());
            }
        }

        //  The set includes all bean types which are Java interfaces, except for java.io.Serializable

View on GitHub (pinned to e1c734241f)

Solutions

  1. Keep exactly one @Delegate field and remove or un-annotate the others
  2. If both are needed, split the decorator into two decorator classes
  3. Delegate to one and implement the other members via normal injection instead of @Delegate

Example fix

// before
@Delegate @Inject Audited a;
@Delegate @Inject Logged l;
// after
@Delegate @Inject Audited a; // l removed or not annotated
Defensive patterns

Strategy: validation

Validate before calling

static void requireSingleDelegate(Class<?> decorator) {
  long n = java.util.Arrays.stream(decorator.getDeclaredFields())
      .filter(f -> f.isAnnotationPresent(jakarta.decorator.Delegate.class)).count();
  if (n > 1) throw new IllegalStateException(decorator + " has " + n + " @Delegate injection points");
}

Type guard

static boolean hasSingleDelegate(Class<?> decorator) {
  return java.util.Arrays.stream(decorator.getDeclaredFields())
      .filter(f -> f.isAnnotationPresent(jakarta.decorator.Delegate.class)).count() == 1;
}

Prevention

When it happens

Trigger: A decorator class declares two or more fields (or constructor parameters) annotated @Delegate - often after merging decorator implementations or copying fields during refactoring.

Common situations: Merging two decorators into one class; keeping an old delegate field after adding a new one; Lombok or code generation duplicating delegate members.

Related errors


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