{"record":{"id":"a3a3648ebb276193","repo":"quarkusio/quarkus","slug":"s-type-can-not-be-used-to-represent-jwt-claims-in","errorCode":null,"errorMessage":"%s type can not be used to represent JWT claims in @Singleton or @ApplicationScoped beans, make the bean @RequestScoped or wrap this type with org.eclipse.microprofile.jwt.ClaimValue or jakarta.inject.Provider or jakarta.enterprise.inject.Instance","messagePattern":"(.+?) type can not be used to represent JWT claims in @Singleton or @ApplicationScoped beans, make the bean @RequestScoped or wrap this type with org\\.eclipse\\.microprofile\\.jwt\\.ClaimValue or jakarta\\.inject\\.Provider or jakarta\\.enterprise\\.inject\\.Instance","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java","lineNumber":186,"sourceCode":"            if (injectionPoint.hasDefaultedQualifier()) {\n                continue;\n            }\n            AnnotationInstance claimQualifier = injectionPoint.getRequiredQualifier(CLAIM_NAME);\n            if (claimQualifier != null) {\n                Type actualType = injectionPoint.getRequiredType();\n\n                Optional<BeanInfo> bean = injectionPoint.getTargetBean();\n                if (bean.isPresent()) {\n                    DotName scope = bean.get().getScope().getDotName();\n                    if (!REQUEST_SCOPED_NAME.equals(scope)\n                            && (!ALL_PROVIDER_NAMES.contains(injectionPoint.getType().name())\n                                    && !CLAIM_VALUE_NAME.equals(actualType.name()))) {\n                        String error = String.format(\n                                \"%s type can not be used to represent JWT claims in @Singleton or @ApplicationScoped beans\"\n                                        + \", make the bean @RequestScoped or wrap this type with org.eclipse.microprofile.jwt.ClaimValue\"\n                                        + \" or jakarta.inject.Provider or jakarta.enterprise.inject.Instance\",\n                                actualType.name());\n                        throw new IllegalStateException(error);\n                    }\n                }\n            }\n\n        }\n    }\n\n    @BuildStep\n    AdditionalBeanBuildItem jwtClaimIntegration(Capabilities capabilities) {\n        if (!capabilities.isPresent(Capability.JWT)) {\n            AdditionalBeanBuildItem.Builder removable = AdditionalBeanBuildItem.builder();\n            removable.addBeanClass(CommonJwtProducer.class);\n            removable.addBeanClass(RawClaimTypeProducer.class);\n            removable.addBeanClass(JsonValueProducer.class);\n            removable.addBeanClass(ClaimValueProducer.class);\n            removable.addBeanClass(Claim.class);\n            return removable.build();\n        }","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/oidc/deployment/src/main/java/io/quarkus/oidc/deployment/OidcBuildStep.java#L168-L204","documentation":"During OIDC build-time processing, checkClaim() verifies that JWT claim injection types (@Claim JwtClaims/JsonValue-like types) are only used in beans whose scope allows per-request values. Injecting such a raw claim type into a @Singleton or @ApplicationScoped bean is rejected with IllegalStateException because the value would be computed once and shared across requests.","triggerScenarios":"Annotating a field of claim type (e.g. JsonValue/JwtClaims style claim) with @Claim in a bean scoped @Singleton or @ApplicationScoped; CDI build-step validation flags the actualType name as non-wrapper and non-ClaimValue.","commonSituations":"Migrating an app from request-scoped services to singletons while keeping @Claim fields; copy-pasting claim injection into a config/utility singleton bean.","solutions":["Make the bean @RequestScoped","Wrap the field type with org.eclipse.microprofile.jwt.ClaimValue<T>","Or inject jakarta.inject.Provider<T> / jakarta.enterprise.inject.Instance<T> instead of the raw claim type"],"exampleFix":"// before\n@ApplicationScoped\nclass UserBean {\n    @Claim(\"sub\") JsonValue subject;\n}\n// after\n@ApplicationScoped\nclass UserBean {\n    @Claim(\"sub\") ClaimValue<JsonValue> subject; // or make the bean @RequestScoped\n}","handlingStrategy":"validation","validationCode":"// At build/design time: never inject raw @Claim types into @Singleton/@ApplicationScoped beans.\n// Use ClaimValue/Provider/Instance wrappers or @RequestScoped scope for the bean.","typeGuard":null,"tryCatchPattern":"try { app.start(); } catch (IllegalStateException e) { if (e.getMessage().contains(\"can not be used to represent JWT claims\")) { /* fix bean scope or wrap type */ } }","preventionTips":["Keep claim-injecting beans @RequestScoped","Use ClaimValue<T> or Provider<T> for singleton beans","Run a build (mvn verify) before deploying — this fails at build time"],"tags":["oidc","cdi","jwt","build-time"],"backgroundTag":"claim-scope-unsupported","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"}