quarkusio/quarkus · error · DefinitionException
Injected @Decorated Bean<> has to use the delegate type as i
Error message
Injected @Decorated Bean<> has to use the delegate type as its type parameter. Problematic injection point: ${targetInfo} What it means
A decorator may inject Bean decoratedInstance with @Decorated. The injection point must be exactly Bean<delegateType> — one type argument equal to the decorator's delegate type — otherwise ArC cannot wire the decorated instance and throws a DefinitionException.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java:837
bytecodeTransformerConsumer
.accept(new BytecodeTransformer(bean.getTarget().get().asClass().name().toString(),
new PrivateInjectedFieldTransformFunction(injection.getTarget().asField())));
}
}
}
if (bean.isDecorator()) {
DecoratorInfo decorator = (DecoratorInfo) bean;
for (InjectionPointInfo injectionPointInfo : bean.getAllInjectionPoints()) {
// the injection point is a field, an initializer method parameter or a bean constructor of a decorator,
// with qualifier @Decorated, then the type parameter of the injected Bean must be the same as the delegate type
if (injectionPointInfo.getRequiredType().name().equals(DotNames.BEAN)
&& injectionPointInfo.getRequiredQualifier(DotNames.DECORATED) != null
&& injectionPointInfo.getRequiredType().kind() == Type.Kind.PARAMETERIZED_TYPE) {
ParameterizedType parameterizedType = injectionPointInfo.getRequiredType().asParameterizedType();
if (parameterizedType.arguments().size() != 1
|| !parameterizedType.arguments().get(0).equals(decorator.getDelegateType())) {
throw new DefinitionException(
"Injected @Decorated Bean<> has to use the delegate type as its type parameter. " +
"Problematic injection point: " + injectionPointInfo.getTargetInfo());
}
}
}
}
}
static void validateBean(BeanInfo bean, List<Throwable> errors, Consumer<BytecodeTransformer> bytecodeTransformerConsumer,
Set<DotName> classesReceivingNoArgsCtor, boolean failIfNotProxyable) {
if (bean.isClassBean()) {
ClassInfo beanClass = bean.getTarget().get().asClass();
String classifier = bean.getScope().isNormal() ? "Normal scoped" : null;
if (classifier == null && bean.isSubclassRequired()) {
classifier = "Intercepted";
failIfNotProxyable = true;
}View on GitHub (pinned to e1c734241f)
Solutions
- Change the injection point's type argument to match the decorator's @Delegate type exactly
- Update the @Delegate field type if the intended delegate type changed
- Remove the @Decorated Bean<> injection point if the decorated instance is not needed
Example fix
// before
@Decorator
abstract class MyDecorator implements Service {
@Inject @Decorated Bean<Object> decorated;
}
// after
@Decorator
abstract class MyDecorator implements Service {
@Inject @Decorated Bean<Service> decorated;
} Defensive patterns
Strategy: validation
Validate before calling
// in a decorator, ensure Bean<> argument matches the delegate type
if (!decoratedBeanType.arguments().get(0).equals(delegateFieldType)) {
throw new IllegalArgumentException("@Decorated Bean<> must match @Delegate type");
} Try / catch
try {
quarkusBuild.start();
} catch (DefinitionException e) {
if (e.getMessage().contains("Injected @Decorated Bean<>")) {
logger.errorf("Align Bean<> type param with delegate type: %s", e.getMessage());
}
throw e;
} Prevention
- Always use Bean<DelegateType> with @Decorated where DelegateType matches @Delegate
- Update both @Delegate and @Decorated Bean<> together when changing delegate types
- Avoid copy-pasting decorator scaffolding without adjusting types
When it happens
Trigger: During decorator validation, an injection point with required type Bean (parameterized) and qualifier @Decorated has argument count != 1, or its single argument does not equal decorator.getDelegateType().
Common situations: Writing Bean<Object> or Bean<SomeOtherType> with @Decorated instead of the delegate type; changing the decorator's @Delegate type without updating the Bean<> parameter; copy-pasting decorator code across decorators with different delegate types.
Related errors
- Unable to derive the logger name at ${injectionPoint}
- Unable to construct type for ${decorator}: ${e.getMessage()}
- Decorated type not found in the bean archive index: ${decora
- The decorator ${decoratorClass} has no @Delegate injection p
- The decorator ${decoratorClass} has multiple @Delegate injec
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c9c98f12872d067a.
Report an issue: GitHub.