calcom/cal.diy · error · ForbiddenException

PermissionsGuard - no oAuth client found for client id=${id}

Error message

PermissionsGuard - no oAuth client found for client id=${id}

What it means

ForbiddenException from PermissionsGuard.getOAuthClientById when oAuthClientRepository.getOAuthClient(id) returns null — the x-cal-client-id header (or clientId route param) does not correspond to any platform OAuth client in the database.

Source

Thrown at apps/api/v2/src/modules/auth/guards/permissions/permissions.guard.ts:89

    return true;
  }

  async getOAuthClientByAccessToken(
    accessToken: string
  ): Promise<Pick<PlatformOAuthClient, "id" | "permissions">> {
    const oAuthClient = await this.tokensRepository.getAccessTokenClient(accessToken);
    if (!oAuthClient) {
      throw new ForbiddenException(
        `PermissionsGuard - no oAuth client found for access token=${accessToken}`
      );
    }
    return oAuthClient;
  }

  async getOAuthClientById(id: string): Promise<Pick<PlatformOAuthClient, "id" | "permissions">> {
    const oAuthClient = await this.oAuthClientRepository.getOAuthClient(id);
    if (!oAuthClient) {
      throw new ForbiddenException(`PermissionsGuard - no oAuth client found for client id=${id}`);
    }
    return oAuthClient;
  }

  getDecodedThirdPartyAccessToken(bearerToken: string) {
    return this.tokensService.getDecodedThirdPartyAccessToken(bearerToken);
  }
}

View on GitHub (pinned to 176037d0af)

Solutions

  1. Verify the x-cal-client-id value matches a client listed in the platform dashboard for THIS environment.
  2. Strip any whitespace/newlines from the header value.
  3. If the client was deleted, create a new OAuth client and update the integration.
  4. Confirm you are sending client_id (the public id), not the secret or the DB id.
Defensive patterns

Strategy: validation

Validate before calling

if (!clientId || typeof clientId !== 'string' || clientId.trim().length === 0) {
  throw new Error('x-cal-client-id header must be a non-empty string');
}

Type guard

function isValidClientId(v: unknown): v is string {
  return typeof v === 'string' && v.trim().length > 0 && !/[\r\n]/.test(v);
}

Prevention

When it happens

Trigger: Calling a PermissionsGuard-protected endpoint with an x-cal-client-id header (or :clientId route param) whose value is not a valid platform OAuth client id — wrong, deleted, typo, or from a different environment.

Common situations: Client id copied from a different environment (staging vs production); OAuth client was deleted/deactivated; header typo or extra whitespace; mixing the public client_id with the internal database id.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/164c5d991201e50c. Report an issue: GitHub.