{"record":{"id":"74de05070138be22","repo":"lcobucci/jwt","slug":"the-token-does-not-have-the-claim-claim","errorCode":null,"errorMessage":"The token does not have the claim \"{claim}\"","messagePattern":"The token does not have the claim \"(.+?)\"","errorType":"exception","errorClass":"Lcobucci\\JWT\\Validation\\ConstraintViolation","httpStatus":null,"severity":"error","filePath":"src/Validation/Constraint/HasClaim.php","lineNumber":32,"sourceCode":"{\n    /** @param non-empty-string $claim */\n    public function __construct(private string $claim)\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}\n","sourceCodeStart":14,"sourceCodeEnd":36,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Validation/Constraint/HasClaim.php#L14-L36","documentation":"HasClaim asserts that the token contains the given custom claim; if the claim set has no such key, it throws ConstraintViolation with this message. It signals the expected claim is missing, not that its value was wrong.","triggerScenarios":"(new HasClaim('role'))->assert($plainToken) where $plainToken->claims() does not contain the key 'role'.","commonSituations":"Tokens issued by an older version of the issuer that didn't add the claim yet; per-client tokens missing optional claims; environment-specific tokens (staging vs production issuers).","solutions":["Update the token issuer to always include the required claim","Make the constraint optional / use Validator::assert multiple times with fallback handling","Catch ConstraintViolation and treat missing claim as a valid-but-unprivileged token if the claim is truly optional"],"exampleFix":"// before (token payload lacking claim)\n{\"sub\": \"123\"}\n// after\n{\"sub\": \"123\", \"role\": \"admin\"}","handlingStrategy":"try-catch","validationCode":"if (!$token instanceof UnencryptedToken || !$token->claims()->has('role')) {\n    // handle missing claim before asserting\n}","typeGuard":null,"tryCatchPattern":"try {\n    $validator->assert($token, new HasClaim('role'));\n} catch (RequiredConstraintsViolated $e) {\n    // claim absent; treat as unprivileged or reject\n}","preventionTips":["Ensure the issuer always includes required custom claims","Version your token schema and reject legacy tokens","Catch ConstraintViolation to distinguish missing vs wrong value"],"tags":["jwt","validation","claims","missing-claim"],"backgroundTag":"schema-validation-failed","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"}