quarkusio/quarkus · error · DefinitionException
Injected @Intercepted Bean<?> has to use unbound wildcard as
Error message
Injected @Intercepted Bean<?> has to use unbound wildcard as its type parameter. Problematic injection point: ${injectionPointInfo.getTargetInfo()} What it means
When Bean<T> is injected with the @Intercepted qualifier, the CDI spec mandates the type parameter be an unbound wildcard (Bean<?>). ArC validates the required type is a parameterized type with exactly one argument — a wildcard with no super bound and java.lang.Object extends bound — and throws this DefinitionException otherwise.
Source
Thrown at independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java:144
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(
"Injected @Intercepted Bean<?> has to use unbound wildcard as its type parameter. " +
"Problematic injection point: " + 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.INTERCEPTOR_BEAN)
&& injectionPointInfo.getRequiredType().kind() == Type.Kind.PARAMETERIZED_TYPE
&& injectionPointInfo.getRequiredType().asParameterizedType().arguments().size() == 1) {
Type actualType = injectionPointInfo.getRequiredType().asParameterizedType().arguments().get(0);
AnnotationTarget ipTarget = injectionPointInfo.getAnnotationTarget();
DotName expectedType = null;
if (ipTarget.kind() == Kind.FIELD) {
expectedType = ipTarget.asField().declaringClass().name();
} else if (ipTarget.kind() == Kind.METHOD_PARAMETER) {
expectedType = ipTarget.asMethodParameter().method().declaringClass().name();
}View on GitHub (pinned to e1c734241f)
Solutions
- Change the injection point to use the unbound wildcard: @Inject @Intercepted Bean<?> bean
- Remove the @Intercepted qualifier if a typed Bean<T> was intended and legal in that context
- Move the injection into an interceptor class (also required — see the @Intercepted placement rule)
Example fix
// before @Inject @Intercepted Bean<MyService> self; // after @Inject @Intercepted Bean<?> self;
Defensive patterns
Strategy: validation
Validate before calling
java.lang.reflect.Type t = MyInterceptor.class.getDeclaredField("bean").getGenericType();
boolean ok = t.getTypeName().equals("jakarta.enterprise.inject.spi.Bean<?>"); Prevention
- Always declare @Intercepted injections as Bean<?> with unbound wildcard
- Never use bounded wildcards or concrete types with @Intercepted
- Remember the injection must also live in an interceptor class
When it happens
Trigger: Injecting @Intercepted with a concrete type parameter (Bean<MyBean>), a bounded wildcard (Bean<? extends X>), a super-bound wildcard (Bean<? super X>), or a non-parameterized raw Bean type.
Common situations: IDE auto-completing a concrete type parameter; misunderstanding that @Intercepted metadata is typed; mixing up rules for plain Bean<T> vs @Intercepted Bean<?> injections.
Related errors
- Invalid injection of @Intercepted Bean<T>, can only be injec
- Type of injected Bean<T> does not match the type of the bean
- Type of injected Interceptor<T> does not match the type of t
- Type of injected Decorator<T> does not match the type of the
- Unsupported wildcard type: ${wildcard}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/45dbcedaae6e8046.
Report an issue: GitHub.