calcom/cal.diy · error · UnauthorizedException

${googleCalendar.error?.message}

Error message

${googleCalendar.error?.message}

What it means

Thrown by the GET /v2/gcal/check endpoint when a Google Calendar credential exists but the calendar provider returns an error during the live connectivity check. The calendars service populates connectedCalendars[].error.message when Google's API rejects the token (expired, revoked, or quota hit). The controller re-throws that provider message as an HTTP 401 Unauthorized so the client knows re-authentication is required.

Source

Thrown at apps/api/v2/src/platform/gcal/gcal.controller.ts:114

    );

    if (!gcalCredentials) {
      throw new BadRequestException("Credentials for google_calendar not found.");
    }

    if (gcalCredentials.invalid) {
      throw new BadRequestException("Invalid google OAuth credentials.");
    }

    const { connectedCalendars } = await this.calendarsService.getCalendars(userId);
    const googleCalendar = connectedCalendars.find(
      (cal: { integration: { type: string } }) => cal.integration.type === GOOGLE_CALENDAR_TYPE
    );
    if (!googleCalendar) {
      throw new UnauthorizedException("Google Calendar not connected.");
    }
    if (googleCalendar.error?.message) {
      throw new UnauthorizedException(googleCalendar.error?.message);
    }

    return { status: SUCCESS_STATUS };
  }
}

View on GitHub (pinned to 176037d0af)

Solutions

  1. Re-authenticate by redirecting the user through GET /v2/gcal/oauth/auth-url to obtain a fresh authorization code and exchange it for new tokens.
  2. Inspect the credential's `invalid` flag in the database — if true, the token is permanently revoked and only re-authorization will fix it.
  3. Read the raw error.message value from the response to distinguish transient issues (rate limit, 503) from permanent ones (invalid_grant, revoked).
  4. Check the Google Cloud Console IAM quotas and enabled API status for the Calendar API to rule out quota exhaustion.
Defensive patterns

Strategy: retry

Validate before calling

// Before calling /v2/gcal/check, verify credential exists
const credentials = await api.get('/v2/gcal/check');
// Pre-flight: check if user has google_calendar credential type
// This doesn't prevent provider errors but catches missing credentials early

Try / catch

try {
  await api.get('/v2/gcal/check');
} catch (error) {
  if (error.response?.status === 401) {
    // Token is expired or revoked — re-initiate OAuth flow
    const { data } = await api.get('/v2/gcal/oauth/auth-url');
    window.location.href = data.data.authUrl;
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: Calling GET /v2/gcal/check after the user revoked Google Calendar access from their Google account security page; calling it with an OAuth refresh token that expired after extended inactivity; calling it during a Google API outage or after exceeding the Google Calendar API daily quota.

Common situations: User disconnects the calendar from their Google account but the Cal.com credential row still exists; OAuth client secrets were rotated in Google Cloud Console without re-issuing user tokens; bulk calendar sync exhausts API quota; token invalidated by a Google password change on the user's account.

Related errors


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