quarkusio/quarkus · error · DefinitionException

Decorator declares a producer field: ${decoratorClass}

Error message

Decorator declares a producer field: ${decoratorClass}

What it means

Build-time CDI definition error: while validating the decorator class, ArC found a field annotated @Produces. Producer fields are forbidden in decorators (decoration happens through the @Delegate injection point only), so the deployment aborts naming the decorator.

Source

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

            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);
                }
            }

            DotName superClass = aClass.superName();
            aClass = superClass != null && !superClass.equals(DotNames.OBJECT)
                    ? getClassByName(beanDeployment.getBeanArchiveIndex(), superClass)
                    : null;
        }
    }

}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove the @Produces field from the decorator.
  2. Move the producer field to a separate non-decorator bean and inject it where needed.
  3. Remove @Decorator if the class was really meant to be a producer bean.
  4. Inspect parent classes as the check walks the hierarchy.

Example fix

// before
@Decorator
public class D implements Greeter {
    @Produces
    Helper helper = new Helper();
}

// after
@Decorator
public class D implements Greeter {
    @Inject Helper helper; // produced by another bean
}
Defensive patterns

Strategy: validation

Validate before calling

if (decoratorClass.getAnnotation(jakarta.decorator.Decorator.class) != null)
    for (Field f : decoratorClass.getFields())
        if (f.isAnnotationPresent(jakarta.enterprise.inject.Produces.class))
            throw new IllegalStateException("Decorator cannot declare producer field: " + f);

Prevention

When it happens

Trigger: A @Decorator class declares a field annotated @Produces, detected during createDecorator's field validation.

Common situations: Class converted from a producer bean into a decorator with the producer field left in place; copy-paste; moving production logic into a decorator by mistake.

Related errors


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