{"record":{"id":"549d2644a4679b40","repo":"lcobucci/jwt","slug":"the-claim-claim-is-a-registered-claim-another-constraint-549d26","errorCode":null,"errorMessage":"The claim \"{claim}\" is a registered claim, another constraint must be used to validate its value","messagePattern":"The claim \"(.+?)\" is a registered claim, another constraint must be used to validate its value","errorType":"exception","errorClass":"Lcobucci\\JWT\\Validation\\Constraint\\CannotValidateARegisteredClaim","httpStatus":null,"severity":"error","filePath":"src/Validation/Constraint/HasClaimWithValue.php","lineNumber":19,"sourceCode":"<?php\ndeclare(strict_types=1);\n\nnamespace Lcobucci\\JWT\\Validation\\Constraint;\n\nuse Lcobucci\\JWT\\Token;\nuse Lcobucci\\JWT\\UnencryptedToken;\nuse Lcobucci\\JWT\\Validation\\Constraint;\nuse Lcobucci\\JWT\\Validation\\ConstraintViolation;\n\nuse function in_array;\n\nfinal readonly class HasClaimWithValue implements Constraint\n{\n    /** @param non-empty-string $claim */\n    public function __construct(private string $claim, private mixed $expectedValue)\n    {\n        if (in_array($claim, Token\\RegisteredClaims::ALL, true)) {\n            throw CannotValidateARegisteredClaim::create($claim);\n        }\n    }\n\n    public function assert(Token $token): void\n    {\n        if (! $token instanceof UnencryptedToken) {\n            throw ConstraintViolation::error('You should pass a plain token', $this);\n        }\n\n        $claims = $token->claims();\n\n        if (! $claims->has($this->claim)) {\n            throw ConstraintViolation::error('The token does not have the claim \"' . $this->claim . '\"', $this);\n        }\n\n        if ($claims->get($this->claim) !== $this->expectedValue) {\n            throw ConstraintViolation::error(\n                'The claim \"' . $this->claim . '\" does not have the expected value',","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Validation/Constraint/HasClaimWithValue.php#L1-L37","documentation":"HasClaimWithValue validates the exact value of a custom claim and, like HasClaim, refuses registered claims (iss, sub, aud, exp, nbf, iat, jti) because dedicated constraints exist for them. Constructing it with a registered claim name throws CannotValidateARegisteredClaim immediately.","triggerScenarios":"new HasClaimWithValue('sub', '123'), new HasClaimWithValue('aud', 'api'), new HasClaimWithValue('exp', ...), etc., i.e. any Token\\RegisteredClaims::ALL member as the claim name.","commonSituations":"Checking issuer/audience values with the generic constraint instead of IssuedBy/PermittedFor; copy-pasting HasClaimWithValue and editing only the expected value; misunderstanding which claims are 'registered'.","solutions":["Use the dedicated constraints: RelatedTo (sub), PermittedFor (aud), IssuedBy (iss), ValidAt (exp/nbf/iat), IdentifiedBy (jti)","Read and compare registered claims manually via $token->claims()->get() if a dedicated constraint doesn't fit","Rename your custom claim if it collides with a registered name"],"exampleFix":"// before\n$c = new HasClaimWithValue('aud', 'my-api');\n// after\n$c = new PermittedFor('my-api');","handlingStrategy":"type-guard","validationCode":"if (in_array($claimName, Token\\RegisteredClaims::ALL, true)) {\n    // use RelatedTo / PermittedFor / IssuedBy / ValidAt instead\n}","typeGuard":"function isCustomClaim(string $claim): bool {\n    return !in_array($claim, Token\\RegisteredClaims::ALL, true);\n}","tryCatchPattern":"try {\n    $constraint = new HasClaimWithValue('role', 'admin');\n} catch (CannotValidateARegisteredClaim $e) {\n    // pick the dedicated constraint for that registered claim\n}","preventionTips":["Never pass iss/sub/aud/exp/nbf/iat/jti to generic constraints","Use a constraint factory mapping claim names to constraint classes","Unit-test constraint construction with your claim allowlist"],"tags":["jwt","validation","constraint","misuse"],"backgroundTag":"invalid-argument-value","analyzedSha":"375813049c24c7111bda8b6884c57b071ceb2fe7","analyzedAt":"2026-09-14T11:12:28.004Z","contentChangedAt":"2026-09-14T11:12:28.004Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}