{"record":{"id":"d329c450e5c9bac5","repo":"quarkusio/quarkus","slug":"found-permissionchecker-annotation-instance-decla","errorCode":null,"errorMessage":"Found @PermissionChecker annotation instance declared on the CDI bean method '%s#%s'.\n                                            The CDI bean is a dependent scoped bean, but only the '@Singleton' bean or normal scoped beans are supported","messagePattern":"Found @PermissionChecker annotation instance declared on the CDI bean method '(.+?)#(.+?)'\\.\n                                            The CDI bean is a dependent scoped bean, but only the '@Singleton' bean or normal scoped beans are supported","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java","lineNumber":887,"sourceCode":"                    .createWith(recorder.createPermissionAugmentor());\n\n            checkerBuilder.instance.getPermissionCheckers().stream().forEach(checkerMethod -> {\n                var checkerClassType = Type.create(checkerMethod.declaringClass().name(), Type.Kind.CLASS);\n\n                // validate permission checker method's declaring class is a CDI bean\n                // synthetic beans are not taken into consideration which makes them not supported\n                var matchingBeans = beanDiscoveryFinishedBuildItem.beanStream().assignableTo(checkerClassType).collect();\n                if (matchingBeans.isEmpty()) {\n                    throw new RuntimeException(\n                            \"\"\"\n                                    @PermissionChecker declared on method '%s', but no matching CDI bean could be found for the declaring class '%s'.\n                                    \"\"\"\n                                    .formatted(checkerMethod.name(), checkerClassType.name()));\n                }\n                // Using @Dependent is problematic because we would have to destroy beans manually at some point (which?)\n                matchingBeans.stream().filter(b -> BuiltinScope.DEPENDENT.getInfo().equals(b.getScope())).findFirst()\n                        .ifPresent(bi -> {\n                            throw new RuntimeException(\n                                    \"\"\"\n                                            Found @PermissionChecker annotation instance declared on the CDI bean method '%s#%s'.\n                                            The CDI bean is a dependent scoped bean, but only the '@Singleton' bean or normal scoped beans are supported\n                                            \"\"\"\n                                            .formatted(checkerMethod.name(), checkerClassType.name()));\n                        });\n\n                syntheticBeanConfigurator.addInjectionPoint(checkerClassType);\n            });\n\n            syntheticBeanProducer.produce(syntheticBeanConfigurator.done());\n\n            // ==== Generate QuarkusPermission for each @PermissionChecker annotation instance\n            checkerBuilder.instance.generatePermissionCheckers(generatedClassProducer, generatedResourceProducer,\n                    generatedServiceProviderProducer);\n        }\n    }\n","sourceCodeStart":869,"sourceCodeEnd":905,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/security/deployment/src/main/java/io/quarkus/security/deployment/SecurityProcessor.java#L869-L905","documentation":"A @PermissionChecker method's declaring bean cannot be @Dependent scoped: Quarkus would have no lifecycle point to destroy such instances. Only @Singleton beans or normal-scoped beans (e.g. @ApplicationScoped) are supported, so the build fails when a dependent-scoped bean hosts a permission checker.","triggerScenarios":"Declaring a @PermissionChecker method on a class with no scope annotation that is still picked up as a @Dependent bean (default scope), or explicitly annotated with @Dependent / @Transactional @Dependent combos.","commonSituations":"Forgetting to add a scope so the class defaults to @Dependent; using @Singleton missing and assuming @Dependent works; annotation like @WithDuplicates or custom stereotype defaulting to dependent scope.","solutions":["Annotate the declaring class with @Singleton (no proxies needed) or a normal scope such as @ApplicationScoped.","Remove @Dependent if explicitly present and replace it with @Singleton or @ApplicationScoped.","Re-run the build to confirm the checker bean resolves to a supported scope."],"exampleFix":"// before\n@Dependent\npublic class PaymentChecker { @PermissionChecker(\"pay\") boolean canPay() { ... } }\n\n// after\n@ApplicationScoped\npublic class PaymentChecker { @PermissionChecker(\"pay\") boolean canPay() { ... } }","handlingStrategy":"validation","validationCode":"// reject @Dependent on permission checker hosts\nboolean bad = PaymentChecker.class.isAnnotationPresent(jakarta.enterprise.context.Dependent.class);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to @ApplicationScoped for checker classes","Never rely on implicit dependent scope for security components","Review scope annotations when adding @PermissionChecker"],"tags":["quarkus","security","cdi","scope","permissionchecker"],"backgroundTag":"unsupported-cdi-scope","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"}