{"record":{"id":"19e1876663b2772c","repo":"quarkusio/quarkus","slug":"invalid-injection-of-interceptor-t-bean-can-only","errorCode":null,"errorMessage":"Invalid injection of Interceptor<T> bean, can only be used in interceptors but was detected in: ${injectionPointInfo.getTargetInfo()}","messagePattern":"Invalid injection of Interceptor<T> bean, can only be used in interceptors but was detected in: (.+?)","errorType":"exception","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java","lineNumber":72,"sourceCode":"\n    private static Injection forSynthetic(Iterable<TypeAndQualifiers> injectionPoints, BeanType beanType) {\n        List<InjectionPointInfo> ret = new ArrayList<>();\n        for (TypeAndQualifiers injectionPoint : injectionPoints) {\n            InjectionPointInfo ip = InjectionPointInfo.fromSyntheticInjectionPoint(injectionPoint);\n            validateInjections(ip, beanType);\n            ret.add(ip);\n        }\n        return new Injection(null, ret);\n    }\n\n    private static void validateInjections(InjectionPointInfo injectionPointInfo, BeanType beanType) {\n        // Mostly validation related to Bean metadata injection restrictions\n        // see https://jakarta.ee/specifications/cdi/4.1/jakarta-cdi-spec-4.1.html#bean_metadata\n        if (beanType == BeanType.MANAGED_BEAN || beanType == BeanType.SYNTHETIC_BEAN || beanType == BeanType.PRODUCER_METHOD) {\n            // If an Interceptor<T> instance is injected into a bean instance other than an interceptor instance,\n            // the container automatically detects the problem and treats it as a definition error.\n            if (injectionPointInfo.getType().name().equals(DotNames.INTERCEPTOR_BEAN)) {\n                throw new DefinitionException(\"Invalid injection of Interceptor<T> bean, can only be used in interceptors \" +\n                        \"but was detected in: \" + injectionPointInfo.getTargetInfo());\n            }\n\n            // If a Bean instance with qualifier @Intercepted is injected into a bean instance other than an interceptor\n            // instance, the container automatically detects the problem and treats it as a definition error.\n            if (injectionPointInfo.getType().name().equals(DotNames.BEAN)\n                    && injectionPointInfo.getRequiredQualifier(DotNames.INTERCEPTED) != null) {\n                throw new DefinitionException(\n                        \"Invalid injection of @Intercepted Bean<T>, can only be injected into interceptors \" +\n                                \"but was detected in: \" + injectionPointInfo.getTargetInfo());\n            }\n\n            // If a Decorator<T> instance is injected into a bean instance other than a decorator instance,\n            // the container automatically detects the problem and treats it as a definition error.\n            if (injectionPointInfo.getType().name().equals(DotNames.DECORATOR)) {\n                throw new DefinitionException(\"Invalid injection of Decorator<T> bean, can only be used in decorators \" +\n                        \"but was detected in: \" + injectionPointInfo.getTargetInfo());\n            }","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Injection.java#L54-L90","documentation":"Per the CDI 4.1 bean-metadata rules, an Interceptor<T> instance may only be injected into an interceptor (or decorator) instance. ArC detects an Interceptor<T> injection point into a regular managed bean, synthetic bean, or producer method at build time and throws this DefinitionException.","triggerScenarios":"Adding an @Inject Interceptor<MyType> (or Instance<Interceptor<...>>) field/parameter/constructor argument to a normal @ApplicationScoped/@RequestScoped bean or producer method instead of to an interceptor class.","commonSituations":"Trying to programmatically inspect or invoke interceptors from business code; copying interceptor metadata injection code out of an interceptor class into a service bean.","solutions":["Move the Interceptor<T> injection point into an interceptor or decorator class","If you only need interceptor behavior, apply the interceptor binding annotation to the bean instead of injecting Interceptor<T>","Remove the injection point entirely if the metadata is not actually needed"],"exampleFix":"// before\n@ApplicationScoped\nclass MyService { @Inject Interceptor<MyService> interceptor; }\n// after\nclass MyServiceInterceptor { @Inject Interceptor<Object> interceptor; }","handlingStrategy":"validation","validationCode":"boolean ok = java.util.Arrays.stream(MyBean.class.getDeclaredFields())\n    .noneMatch(f -> f.getType().getName().equals(\"jakarta.enterprise.inject.spi.Interceptor\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never inject Interceptor<T> into regular beans; only interceptors/decorators","Use interceptor binding annotations on the bean instead of manual metadata injection","Review imports of jakarta.enterprise.inject.spi.* in business beans"],"tags":["cdi","arc","interceptor","bean-metadata","build-time"],"backgroundTag":"cdi-bean-metadata-injection","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}