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.SerializableView on GitHub (pinned to e1c734241f)
Solutions
- Keep exactly one @Delegate field and remove or un-annotate the others
- If both are needed, split the decorator into two decorator classes
- 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
- Only one field per decorator may carry @Delegate
- When merging decorators, strip duplicate delegate fields
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
- The decorator ${decoratorClass} has no @Delegate injection p
- Unable to construct type for ${decorator}: ${e.getMessage()}
- Decorated type not found in the bean archive index: ${decora
- A decorator must be @Dependent but ${decoratorClass} declare
- Quarkus does not support CDI Full @Specializes annotation; t
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/a4a9126b513d2122.
Report an issue: GitHub.