quarkusio/quarkus · error · DefinitionException

Type of injected Bean<T> does not match the type of the bean

Error message

Type of injected Bean<T> does not match the type of the bean declaring the injection point. Problematic injection point: ${injectionPointInfo.getTargetInfo()}

What it means

When Bean<T> is injected into a bean with qualifier @Default, the CDI spec requires T to match the declaring bean's own type. ArC performs a (deliberately rudimentary) check comparing the injection point's declaring class against the Bean<T> type parameter and throws this DefinitionException when they differ.

Source

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

                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) {
                    // the injection point is a producer method parameter then the type parameter of the injected Bean
                    // must be the same as the producer method return type
                    if (beanType == BeanType.PRODUCER_METHOD) {
                        expectedType = ipTarget.asMethodParameter().method().returnType().name();
                    } else {
                        expectedType = ipTarget.asMethodParameter().method().declaringClass().name();
                    }
                }
                if (expectedType != null
                        // This is very rudimentary check, might need to be expanded?
                        && !expectedType.equals(actualType.name())) {
                    throw new DefinitionException(
                            "Type of injected Bean<T> does not match the type of the bean declaring the " +
                                    "injection point. Problematic injection point: " + injectionPointInfo.getTargetInfo());
                }
            }
        }
        if (beanType == BeanType.INTERCEPTOR) {
            // the injection point is a field, an initializer method parameter or a bean constructor of an interceptor,
            // with qualifier @Intercepted, then the type parameter of the injected Bean must be an unbounded wildcard
            if (injectionPointInfo.getRequiredType().name().equals(DotNames.BEAN)
                    && injectionPointInfo.getRequiredQualifier(DotNames.INTERCEPTED) != null
                    && injectionPointInfo.getRequiredType().kind() == Type.Kind.PARAMETERIZED_TYPE) {
                ParameterizedType parameterizedType = injectionPointInfo.getRequiredType().asParameterizedType();
                // there should be exactly one param - wildcard - and it has to be unbound; all else is DefinitionException
                if (parameterizedType.arguments().size() != 1
                        || !(parameterizedType.arguments().get(0).kind() == Type.Kind.WILDCARD_TYPE)
                        || !(parameterizedType.arguments().get(0).asWildcardType().extendsBound().name().equals(DotNames.OBJECT)
                                && parameterizedType.arguments().get(0).asWildcardType().superBound() == null)) {
                    throw new DefinitionException(

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the type parameter to the exact type of the bean declaring the injection point
  2. Use an unbound wildcard Bean<?> if you don't need the typed parameter (note: specific wildcard rules apply)
  3. Remove the @Default qualifier / injection if it was unintentional

Example fix

// before
class MyService { @Inject Bean<OtherService> otherMeta; }
// after
class MyService { @Inject Bean<MyService> selfMeta; }
Defensive patterns

Strategy: validation

Validate before calling

Field f = MyBean.class.getDeclaredField("meta");
if (Bean.class == f.getType() && f.getAnnotations().length == 0)
    throw new IllegalStateException("Bean<T> with @Default must use T = " + MyBean.class.getName());

Prevention

When it happens

Trigger: Injecting Bean<SomeOtherType> (with @Default qualifier) into a bean of a different type, e.g. class Foo { @Inject Bean<Bar> barMeta; }.

Common situations: Copying metadata injection snippets between classes without changing the type parameter; using Object or a base class instead of the exact declaring bean type.

Related errors


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