passbolt/passbolt_api · error · BadRequestException
No claims
Error message
No claims
What it means
assertTokenClaims is the entry point for validating the decoded JWT claims. If the claims array decoded from the id_token is empty, it throws BadRequestException('No claims') before running the individual aud/iss/email assertions. An empty claim set means the token carried no payload data at all.
Solutions
- Re-obtain a fresh id_token from the provider — the current one has no usable payload.
- Verify the token was not altered/stripped in transit (proxies or client code rewriting the token).
- If calling assertTokenClaims directly (tests/tools), pass the full decoded claims array, not an empty one.
Defensive patterns
Strategy: validation
Validate before calling
$claims = (array)JWT::decode($idToken, $keys);
if (empty($claims)) {
throw new RuntimeException('Decoded token has no claims; obtain a fresh id_token');
} Type guard
function hasClaims(array $tokenClaims): bool {
return !empty($tokenClaims);
} Try / catch
try {
$token->assertTokenClaims($claims);
} catch (BadRequestException $e) {
if ($e->getMessage() === 'No claims') { /* token unusable: re-run OAuth flow */ }
} Prevention
- Only feed assertTokenClaims with the full decoded JWT payload
- Treat empty-claim tokens as corrupt: request a new id_token rather than retrying validation
- Avoid manual token manipulation in tests that strips the payload
When it happens
Trigger: assertTokenClaims called (directly or via __construct during token instantiation) with an empty array — i.e. JWT::decode succeeded but produced no claims, or a caller passed an empty array manually.
Common situations: Rare in practice; usually seen in unit tests calling assertTokenClaims([]) or when a hand-crafted/damaged JWT decoded to an empty payload.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- The aud (client id) parameter is invalid.
- The email claim is not found or invalid.
- The iss (issuer) parameter does not match.
- The iss (issuer) parameter is invalid.
- JWT token is missing.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/b6ecf5f9c2883350.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Utility/OpenId/BaseIdToken.php:110
throw $exception;
}
$this->idTokenClaims = $tokenClaims;
}
/**
* Validate the access token claims from an access token you received in your application.
* Note: nbf and exp claims are validated in JWT::decode
*
* @param array $tokenClaims The token claims from an access token you received in the authorization header.
* @throws \Cake\Http\Exception\BadRequestException if any of the claim is invalid
* @return void
*/
public function assertTokenClaims(array $tokenClaims): void
{
if (empty($tokenClaims)) {
throw new BadRequestException('No claims');
}
$this->assertAudClaim($tokenClaims);
$this->assertIssClaim($tokenClaims);
$this->assertEmailClaim($tokenClaims);
}
/**
* Validation email claim against application email validation rule
*
* @param array $tokenClaims claims
* @return void
* @throws \Cake\Http\Exception\BadRequestException if the claim does not validate
*/
public function assertEmailClaim(array $tokenClaims): void
{
$emailClaim = Configure::read('passbolt.plugins.sso.security.oauth2.emailClaimAlias') ?? 'email';
View on GitHub (pinned to 31c1bbc10f)