quarkusio/quarkus · error · DefinitionException

Type of injected Interceptor<T> does not match the type of t

Error message

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

What it means

When Interceptor<T> is injected with qualifier @Default, the CDI spec requires T to match the type of the bean declaring the injection point (i.e., the interceptor itself). ArC compares the injection point's declaring class to T and throws this DefinitionException when they differ.

Source

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

            }
            // 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();
                }
                if (expectedType != null
                        // This is very rudimentary check, might need to be expanded?
                        && !expectedType.equals(actualType.name())) {
                    throw new DefinitionException(
                            "Type of injected Interceptor<T> does not match the type of the bean declaring the " +
                                    "injection point. Problematic injection point: " + injectionPointInfo.getTargetInfo());
                }
            }
        }
        if (beanType == BeanType.DECORATOR) {
            // the injection point is a field, an initializer method parameter or a bean constructor, with qualifier
            // @Default, then the type parameter of the injected Decorator must be the same as the type
            // declaring the injection point
            if (injectionPointInfo.getRequiredType().name().equals(DotNames.DECORATOR)
                    && 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) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set the type parameter to the exact type of the interceptor class declaring the injection point
  2. Use Interceptor<?> with unbound wildcard if you don't need the typed form (verify the qualifier rules)
  3. Remove the injection if the metadata is unused

Example fix

// before
class MyInterceptor { @Inject Interceptor<OtherBean> meta; }
// after
class MyInterceptor { @Inject Interceptor<MyInterceptor> meta; }
Defensive patterns

Strategy: validation

Validate before calling

Field f = MyInterceptor.class.getDeclaredField("meta");
if (f.getGenericType().getTypeName().contains("Interceptor<") && !f.getGenericType().getTypeName().endsWith("<MyInterceptor>"))
    throw new IllegalStateException("Interceptor<T> must match the declaring interceptor type");

Prevention

When it happens

Trigger: Injecting Interceptor<SomeOtherType> into an interceptor (or decorator) whose own type differs, e.g. class MyInterceptor { @Inject Interceptor<Other> other; }.

Common situations: Copying Bean<T> metadata examples into interceptor classes with the wrong type parameter; using a base/interface type instead of the interceptor's own type.

Related errors


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