quarkusio/quarkus · error · DefinitionException

Invalid injection of @Decorated Bean<T>, can only be injecte

Error message

Invalid injection of @Decorated Bean<T>, can only be injected into decorators but was detected in: ${injectionPointInfo.getTargetInfo()}

What it means

Per CDI 4.1, a Bean instance qualified @Decorated may only be injected into a decorator instance. ArC detects such an injection into a regular managed bean, synthetic bean, or producer method at build time and throws this DefinitionException.

Source

Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:96

            if (injectionPointInfo.getType().name().equals(DotNames.BEAN)
                    && injectionPointInfo.getRequiredQualifier(DotNames.INTERCEPTED) != null) {
                throw new DefinitionException(
                        "Invalid injection of @Intercepted Bean<T>, can only be injected into interceptors " +
                                "but was detected in: " + injectionPointInfo.getTargetInfo());
            }

            // If a Decorator<T> instance is injected into a bean instance other than a decorator instance,
            // the container automatically detects the problem and treats it as a definition error.
            if (injectionPointInfo.getType().name().equals(DotNames.DECORATOR)) {
                throw new DefinitionException("Invalid injection of Decorator<T> bean, can only be used in decorators " +
                        "but was detected in: " + injectionPointInfo.getTargetInfo());
            }

            // If a Bean instance with qualifier @Decorated is injected into a bean instance other than a decorator
            // instance, the container automatically detects the problem and treats it as a definition error.
            if (injectionPointInfo.getType().name().equals(DotNames.BEAN)
                    && injectionPointInfo.getRequiredQualifier(DotNames.DECORATED) != null) {
                throw new DefinitionException(
                        "Invalid injection of @Decorated Bean<T>, can only be injected into decorators " +
                                "but was detected in: " + injectionPointInfo.getTargetInfo());
            }

            // the injection point is a field, an initializer method parameter or a bean constructor, with qualifier
            // @Default, then the type parameter of the injected Bean, or Interceptor must be the same as the type
            // declaring the injection point
            if (injectionPointInfo.getRequiredType().name().equals(DotNames.BEAN)
                    && injectionPointInfo.getRequiredType().kind() == Type.Kind.PARAMETERIZED_TYPE
                    && injectionPointInfo.getRequiredType().asParameterizedType().arguments().size() == 1
                    && injectionPointInfo.hasDefaultedQualifier()) {
                Type actualType = injectionPointInfo.getRequiredType().asParameterizedType().arguments().get(0);
                AnnotationTarget ipTarget = injectionPointInfo.getAnnotationTarget();
                DotName expectedType = null;
                if (ipTarget.kind() == Kind.FIELD) {
                    // field injection derives this from the class
                    expectedType = ipTarget.asField().declaringClass().name();
                } else if (ipTarget.kind() == Kind.METHOD_PARAMETER) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Move the @Decorated Bean<T> injection into a @Decorator class
  2. Remove the @Decorated qualifier if plain Bean<T> metadata suffices
  3. Use Instance<T>/programmatic lookup if the actual instance is what you need

Example fix

// before
@ApplicationScoped class Svc { @Inject @Decorated Bean<Svc> self; }
// after
@Decorator class SvcDecorator { @Inject @Decorated Bean<Object> decoratedBean; }
Defensive patterns

Strategy: validation

Validate before calling

boolean ok = java.util.Arrays.stream(MyBean.class.getDeclaredFields())
    .noneMatch(f -> f.isAnnotationPresent(jakarta.enterprise.inject.Decorated.class));

Prevention

When it happens

Trigger: Injecting @Inject @Decorated Bean<MyBean> into a non-decorator bean, synthetic bean, or producer method.

Common situations: Attempting to access decorated-bean metadata outside decorators; adapting interceptor-only examples to decorators; generic metadata helpers.

Related errors


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