quarkusio/quarkus · error · DefinitionException
Decorator declares a producer method: ${decoratorClass}
Error message
Decorator declares a producer method: ${decoratorClass} What it means
CDI definition error thrown at build time by the ArC processor while validating a decorator class (including its superclasses): a decorator must only decorate via a @Delegate injection point, and a method annotated @Produces turns it into a producer, which the CDI spec forbids inside decorators. The offending class is the decorator named in the message.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Decorators.java:164
method.appendTo(message);
message.append("\n");
}
throw new DefinitionException(message.toString());
}
}
checkDecoratorFieldsAndMethods(decoratorClass, beanDeployment);
return new DecoratorInfo(decoratorClass, beanDeployment, delegateInjectionPoint,
decoratedTypes, injections, priority);
}
private static void checkDecoratorFieldsAndMethods(ClassInfo decoratorClass, BeanDeployment beanDeployment) {
ClassInfo aClass = decoratorClass;
while (aClass != null) {
for (MethodInfo method : aClass.methods()) {
if (beanDeployment.hasAnnotation(method, DotNames.PRODUCES)) {
throw new DefinitionException("Decorator declares a producer method: " + decoratorClass);
}
// the following 3 checks rely on the annotation store returning parameter annotations for methods
if (beanDeployment.hasAnnotation(method, DotNames.DISPOSES)) {
throw new DefinitionException("Decorator declares a disposer method: " + decoratorClass);
}
if (beanDeployment.hasAnnotation(method, DotNames.OBSERVES)) {
throw new DefinitionException("Decorator declares an observer method: " + decoratorClass);
}
if (beanDeployment.hasAnnotation(method, DotNames.OBSERVES_ASYNC)) {
throw new DefinitionException("Decorator declares an async observer method: " + decoratorClass);
}
}
for (FieldInfo field : aClass.fields()) {
if (beanDeployment.hasAnnotation(field, DotNames.PRODUCES)) {
throw new DefinitionException("Decorator declares a producer field: " + decoratorClass);
}
}View on GitHub (pinned to e1c734241f)
Solutions
- Remove the @Produces method from the decorator class.
- Move the producer to a separate non-decorator bean and inject it where needed.
- If the class should be a producer bean, remove the @Decorator annotation and give it a proper bean-defining annotation.
- Check superclasses too — the validation walks the hierarchy.
Example fix
// before
@Decorator
public class LoggingGreeting implements Greeter {
@Produces
Helper helper() { return new Helper(); }
}
// after
@Decorator
public class LoggingGreeting implements Greeter {
@Inject Helper helper; // produced elsewhere
} Defensive patterns
Strategy: validation
Validate before calling
if (decoratorClass.getAnnotation(jakarta.decorator.Decorator.class) != null)
for (Method m : decoratorClass.getMethods())
if (m.isAnnotationPresent(jakarta.enterprise.inject.Produces.class))
throw new IllegalStateException("Decorator cannot declare producer: " + m); Prevention
- Never mix @Decorator with @Produces methods; move producers to a dedicated bean.
- Add an ArchUnit rule: classes annotated @Decorator must not contain @Produces/@Disposes/@Observes members.
When it happens
Trigger: A class annotated @Decorator (or inheriting from one) contains a method annotated @Produces, discovered while creating the DecoratorInfo.
Common situations: Converting an ordinary bean that produced helper objects into a decorator without removing producer methods; copy-paste of a producer into a decorator; annotation left behind after refactor.
Related errors
- Decorator declares a producer field: ${decoratorClass}
- Decorator declares a disposer method: ${decoratorClass}
- Decorator declares an observer method: ${decoratorClass}
- Decorator declares an async observer method: ${decoratorClas
- No producer method or field declared by the bean class that
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/3f55e69064a272fc.
Report an issue: GitHub.