calcom/cal.diy · error · BadRequestException
Invalid google OAuth credentials.
Error message
Invalid google OAuth credentials.
What it means
Thrown by GoogleCalendarService.checkIfCalendarConnected (gcal.service.ts:111) as BadRequestException (HTTP 400) when the google_calendar credential row exists but its 'invalid' flag is true. A prior token-refresh or API call failed and flagged the credential; Google OAuth refresh tokens also expire after 6 months of inactivity.
Source
Thrown at apps/api/v2/src/platform/calendars/services/gcal.service.ts:111
const { client_id, client_secret } = this.gcalResponseSchema.parse(app.keys);
const oAuth2Client = new OAuth2Client(client_id, client_secret, redirectUri);
return oAuth2Client;
}
async checkIfCalendarConnected(userId: number): Promise<{ status: typeof SUCCESS_STATUS }> {
const gcalCredentials = await this.credentialRepository.findCredentialByTypeAndUserId(
"google_calendar",
userId
);
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 };
}
async saveCalendarCredentialsAndRedirect(
code: string,View on GitHub (pinned to 176037d0af)
Solutions
- Re-run the Google OAuth connect→save flow, which generates a fresh credential and clears invalid (prompt:'consent' is already set to force new tokens).
- If you changed OAuth scopes, verify the new scopes match CALENDAR_SCOPES in gcal.service.ts.
- After save, confirm invalid=false before retrying check.
Example fix
// before: re-checking a flagged credential
await api.get('/v2/calendars/google_calendar/check'); // 400 'Invalid google OAuth credentials.'
// after: force a fresh consent flow
const { data } = await api.post('/v2/calendars/google_calendar/connect', {});
// user re-authorizes at data.authUrl (prompt=consent)
await api.post('/v2/calendars/google_calendar/save', { code, ... });
await api.get('/v2/calendars/google_calendar/check'); // 200 Defensive patterns
Strategy: validation
Validate before calling
// Detect an invalid google credential via the list before check
const { data } = await api.get('/v2/calendars');
const gcal = data.connectedCalendars.find(c => c.integration?.type === 'google_calendar');
if (gcal?.error || gcal === undefined) {
// invalid or missing — re-run consent
await startGoogleOAuth();
} Type guard
function isCredentialValid(cred) {
return !!cred && cred.invalid === false;
} Try / catch
try {
await api.get('/v2/calendars/google_calendar/check');
} catch (e) {
if (e.response?.status === 400 && /invalid/i.test(e.response?.data?.message)) {
// force fresh consent (prompt=consent is already set server-side)
await startGoogleOAuth();
return;
}
throw e;
} Prevention
- Re-run the OAuth consent flow whenever the credential is flagged invalid — do not retry check.
- Keep OAuth scopes stable; scope changes require re-consent.
- Background-refresh failures should invalidate the flag and notify the user, not stay silent.
When it happens
Trigger: User revoked access from their Google account security page; refresh token expired due to long inactivity; OAuth scopes changed requiring re-consent; a background refresh failure set the flag.
Common situations: Revoked app access; dormant user returning after months; Google project credential rotation.
Related errors
- Credentials for google_calendar not found.
- No valid credentials available for Google Calendar
- Google Calendar is not connected for this user
- Google Calendar credentials are invalid. Please reconnect.
- Calendar credentials are invalid. Please reconnect.
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/f4b232ccc80fa038.
Report an issue: GitHub.