{"record":{"id":"c9c98f12872d067a","repo":"quarkusio/quarkus","slug":"injected-decorated-bean-has-to-use-the-delegate","errorCode":null,"errorMessage":"Injected @Decorated Bean<> has to use the delegate type as its type parameter. Problematic injection point: ${targetInfo}","messagePattern":"Injected @Decorated Bean<> has to use the delegate type as its type parameter\\. Problematic injection point: (.+?)","errorType":"exception","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java","lineNumber":837,"sourceCode":"                    bytecodeTransformerConsumer\n                            .accept(new BytecodeTransformer(bean.getTarget().get().asClass().name().toString(),\n                                    new PrivateInjectedFieldTransformFunction(injection.getTarget().asField())));\n                }\n            }\n        }\n\n        if (bean.isDecorator()) {\n            DecoratorInfo decorator = (DecoratorInfo) bean;\n            for (InjectionPointInfo injectionPointInfo : bean.getAllInjectionPoints()) {\n                // the injection point is a field, an initializer method parameter or a bean constructor of a decorator,\n                // with qualifier @Decorated, then the type parameter of the injected Bean must be the same as the delegate type\n                if (injectionPointInfo.getRequiredType().name().equals(DotNames.BEAN)\n                        && injectionPointInfo.getRequiredQualifier(DotNames.DECORATED) != null\n                        && injectionPointInfo.getRequiredType().kind() == Type.Kind.PARAMETERIZED_TYPE) {\n                    ParameterizedType parameterizedType = injectionPointInfo.getRequiredType().asParameterizedType();\n                    if (parameterizedType.arguments().size() != 1\n                            || !parameterizedType.arguments().get(0).equals(decorator.getDelegateType())) {\n                        throw new DefinitionException(\n                                \"Injected @Decorated Bean<> has to use the delegate type as its type parameter. \" +\n                                        \"Problematic injection point: \" + injectionPointInfo.getTargetInfo());\n                    }\n                }\n            }\n        }\n    }\n\n    static void validateBean(BeanInfo bean, List<Throwable> errors, Consumer<BytecodeTransformer> bytecodeTransformerConsumer,\n            Set<DotName> classesReceivingNoArgsCtor, boolean failIfNotProxyable) {\n\n        if (bean.isClassBean()) {\n            ClassInfo beanClass = bean.getTarget().get().asClass();\n            String classifier = bean.getScope().isNormal() ? \"Normal scoped\" : null;\n            if (classifier == null && bean.isSubclassRequired()) {\n                classifier = \"Intercepted\";\n                failIfNotProxyable = true;\n            }","sourceCodeStart":819,"sourceCodeEnd":855,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java#L819-L855","documentation":"A decorator may inject Bean decoratedInstance with @Decorated. The injection point must be exactly Bean<delegateType> — one type argument equal to the decorator's delegate type — otherwise ArC cannot wire the decorated instance and throws a DefinitionException.","triggerScenarios":"During decorator validation, an injection point with required type Bean (parameterized) and qualifier @Decorated has argument count != 1, or its single argument does not equal decorator.getDelegateType().","commonSituations":"Writing Bean<Object> or Bean<SomeOtherType> with @Decorated instead of the delegate type; changing the decorator's @Delegate type without updating the Bean<> parameter; copy-pasting decorator code across decorators with different delegate types.","solutions":["Change the injection point's type argument to match the decorator's @Delegate type exactly","Update the @Delegate field type if the intended delegate type changed","Remove the @Decorated Bean<> injection point if the decorated instance is not needed"],"exampleFix":"// before\n@Decorator\nabstract class MyDecorator implements Service {\n  @Inject @Decorated Bean<Object> decorated;\n}\n// after\n@Decorator\nabstract class MyDecorator implements Service {\n  @Inject @Decorated Bean<Service> decorated;\n}","handlingStrategy":"validation","validationCode":"// in a decorator, ensure Bean<> argument matches the delegate type\nif (!decoratedBeanType.arguments().get(0).equals(delegateFieldType)) {\n    throw new IllegalArgumentException(\"@Decorated Bean<> must match @Delegate type\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    quarkusBuild.start();\n} catch (DefinitionException e) {\n    if (e.getMessage().contains(\"Injected @Decorated Bean<>\")) {\n        logger.errorf(\"Align Bean<> type param with delegate type: %s\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Always use Bean<DelegateType> with @Decorated where DelegateType matches @Delegate","Update both @Delegate and @Decorated Bean<> together when changing delegate types","Avoid copy-pasting decorator scaffolding without adjusting types"],"tags":["cdi","arc","decorator","injection-point"],"backgroundTag":"decorated-bean-type-mismatch","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"}