{"record":{"id":"1f564b9f03e83049","repo":"quarkusio/quarkus","slug":"bindingssource-may-only-define-a-class-type-got","errorCode":null,"errorMessage":"@BindingsSource may only define a class type, got ${kind}: ${producerMethod}","messagePattern":"@BindingsSource may only define a class type, got (.+?): (.+?)","errorType":"exception","errorClass":"DefinitionException","httpStatus":null,"severity":"error","filePath":"independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java","lineNumber":213,"sourceCode":"        }\n\n        InterceptionProxyInfo interceptionProxy = null;\n        for (MethodParameterInfo parameter : producerMethod.parameters()) {\n            if (parameter.type().name().equals(DotNames.INTERCEPTION_PROXY)) {\n                if (interceptionProxy != null) {\n                    throw new DefinitionException(\n                            \"Declaring more than one InterceptionProxy parameter is invalid: \" + producerMethod);\n                }\n                if (parameter.type().kind() != Kind.PARAMETERIZED_TYPE) {\n                    throw new DefinitionException(\n                            \"InterceptionProxy parameter must be a parameterized type: \" + producerMethod);\n                }\n                DotName targetClass = producerMethod.returnType().name();\n                DotName bindingsSource = null;\n                if (parameter.hasAnnotation(DotNames.BINDINGS_SOURCE)) {\n                    Type bindingsSourceType = parameter.annotation(DotNames.BINDINGS_SOURCE).value().asClass();\n                    if (bindingsSourceType.kind() != Kind.CLASS) {\n                        throw new DefinitionException(\"@BindingsSource may only define a class type, got \"\n                                + bindingsSourceType.kind() + \": \" + producerMethod);\n                    }\n                    bindingsSource = bindingsSourceType.name();\n                }\n                interceptionProxy = new InterceptionProxyInfo(targetClass, bindingsSource);\n            }\n        }\n\n        List<Injection> injections = Injection.forBean(producerMethod, declaringBean, beanDeployment, transformer,\n                Injection.BeanType.PRODUCER_METHOD);\n        BeanInfo bean = new BeanInfo(producerMethod, beanDeployment, scope, typeClosure.types(), qualifiers, injections,\n                declaringBean, disposer, isAlternative, stereotypes, name, isDefaultBean, null, priority,\n                typeClosure.unrestrictedTypes(), interceptionProxy);\n        for (Injection injection : injections) {\n            injection.init(bean);\n        }\n        return bean;\n    }","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/Beans.java#L195-L231","documentation":"When an InterceptionProxy parameter carries @BindingsSource, the annotation's value must be a class type (Kind.CLASS), since it names the class holding the interceptor bindings. Array, primitive, parameterized, or other type kinds are invalid, so ArC throws a DefinitionException during producer method creation.","triggerScenarios":"Beans.createProducerMethod processes an InterceptionProxy parameter annotated @BindingsSource whose annotation value resolves to a Type whose kind() != Kind.CLASS (e.g. an array or nested parameterized type was used as the value).","commonSituations":"Writing @BindingsSource(someArrayOrComplexConstant) by mistake; refactoring that changed the @BindingsSource value from a class literal to another annotation member; generated code emitting non-class values.","solutions":["Change the @BindingsSource value to a plain class literal, e.g. @BindingsSource(MyBindings.class)","Verify the class named by @BindingsSource exists and compiles","Remove @BindingsSource if default bindings derived from the target type are sufficient"],"exampleFix":"// before\n@Produces\nMyService produce(InterceptionProxy<MyService> proxy) { ... }\n// with @BindingsSource(value = SOMETHING_NOT_A_CLASS)\n// after\n@BindingsSource(MyBindings.class)\n@Produces\nMyService produce(InterceptionProxy<MyService> proxy) { ... }","handlingStrategy":"validation","validationCode":"// before declaring\nAnnotationInstance bs = param.annotation(DotNames.BINDINGS_SOURCE);\nif (bs != null && bs.value().asClass().kind() != org.jboss.jandex.Type.Kind.CLASS) {\n    throw new IllegalArgumentException(\"@BindingsSource value must be a class literal\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    arcProcessor.validate(...);\n} catch (DefinitionException e) {\n    if (e.getMessage().contains(\"@BindingsSource may only define a class type\")) {\n        logger.errorf(\"Use a class literal for @BindingsSource: %s\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Always use a class literal as @BindingsSource value","Keep the bindings source class in a compiled, indexable package","Review custom annotation values after refactors"],"tags":["cdi","arc","bean-definition","annotations"],"backgroundTag":"bindings-source-invalid-type","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"}