calcom/cal.diy · error · ForbiddenException
PermissionsGuard - oAuth client with id=${oAuthClient.id} do
Error message
PermissionsGuard - oAuth client with id=${oAuthClient.id} does not have the required permissions=${requiredPermissions}. Go to platform dashboard settings and add the required permissions to the oAuth client. What it means
ForbiddenException from PermissionsGuard when the resolved OAuth client lacks one or more of the route's required permissions. The message lists the oAuthClient.id and the human-readable required permission names (transformed by oAuthClientsOutputService.transformOAuthClientPermission) and points the user to the platform dashboard to add them. Permissions are checked via hasPermissions(oAuthClient.permissions, requiredPermissions).
Source
Thrown at apps/api/v2/src/modules/auth/guards/permissions/permissions.guard.ts:60
// only check permissions for accessTokens attached to platform oAuth Client or platform oAuth credentials, not for next token or api key or third party oauth client
if (nextAuthToken || apiKey || isThirdPartyBearerToken) {
return true;
}
if (!bearerToken && !oAuthClientId) {
throw new ForbiddenException(
"PermissionsGuard - no authentication provided. Provide either authorization bearer token containing managed user access token or oAuth client id in 'x-cal-client-id' header."
);
}
const oAuthClient = bearerToken
? await this.getOAuthClientByAccessToken(bearerToken)
: await this.getOAuthClientById(oAuthClientId);
const hasRequiredPermissions = hasPermissions(oAuthClient.permissions, [...requiredPermissions]);
if (!hasRequiredPermissions) {
throw new ForbiddenException(
`PermissionsGuard - oAuth client with id=${
oAuthClient.id
} does not have the required permissions=${requiredPermissions
.map((permission) => this.oAuthClientsOutputService.transformOAuthClientPermission(permission))
.join(
", "
)}. Go to platform dashboard settings and add the required permissions to the oAuth client.`
);
}
return true;
}
async getOAuthClientByAccessToken(
accessToken: string
): Promise<Pick<PlatformOAuthClient, "id" | "permissions">> {
const oAuthClient = await this.tokensRepository.getAccessTokenClient(accessToken);
if (!oAuthClient) {View on GitHub (pinned to 176037d0af)
Solutions
- Open the Cal.com platform dashboard → OAuth client settings and add every permission listed in the error message to that client.
- If the permission set looks correct, confirm you are authenticating as the right OAuth client (check the oAuthClient.id in the message).
- As a platform maintainer: verify the @Permissions(...) decorator on the route lists only what it truly needs; trim over-broad requirements.
- Regenerate/issue a new access token after updating permissions if the cached token predates the change.
Defensive patterns
Strategy: validation
Validate before calling
const required = ['READ_BOOKINGS']; /* route metadata */
const granted = oAuthClient.permissions; /* string[] */
const ok = required.every(p => granted.includes(p));
if (!ok) {
// tell user to add missing permissions in the dashboard
} Type guard
function clientHasPermissions(client: { permissions: string[] }, required: string[]): boolean {
return required.every(p => client.permissions.includes(p));
} Prevention
- When creating an OAuth client, grant the full set of permissions the integration will need.
- After changing permissions, mint a new access token.
- Keep route @Permissions(...) decorators minimal.
When it happens
Trigger: Calling a PermissionsGuard-protected endpoint whose @Permissions(...) metadata includes a permission not granted to the OAuth client identified by the Bearer access token or the x-cal-client-id. Example: an endpoint requiring READ_BOOKINGS while the client only has READ_USERS.
Common situations: New endpoint shipped behind a permission the existing OAuth client doesn't have; client created with a minimal scope and now calling a broader endpoint; permission name renamed; dashboard permissions UI out of sync with code constants.
Related errors
- PermissionsGuard - no authentication provided. Provide eithe
- PermissionsGuard - no oAuth client found for access token=${
- PermissionsGuard - no oAuth client found for client id=${id}
- RolesGuard - user with id=${user.id} does not have the minim
- RolesGuard - User is not a member of the organization with i
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/f611c4c25b897e8f.
Report an issue: GitHub.