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
- Change the type parameter to the exact type of the bean declaring the injection point
- Use an unbound wildcard Bean<?> if you don't need the typed parameter (note: specific wildcard rules apply)
- 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
- Match the type parameter to the declaring bean class exactly
- Use Bean<?> only where the spec allows wildcards
- Double-check metadata injection snippets copied between classes
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
- Type of injected Interceptor<T> does not match the type of t
- Type of injected Decorator<T> does not match the type of the
- Invalid injection of Interceptor<T> bean, can only be used i
- Invalid injection of @Intercepted Bean<T>, can only be injec
- Invalid injection of Decorator<T> bean, can only be used in
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/33200d7dc2ac78e0.
Report an issue: GitHub.