calcom/cal.diy · error · BadRequestException
Credentials for google_calendar not found.
Error message
Credentials for google_calendar not found.
What it means
Thrown by GoogleCalendarService.checkIfCalendarConnected (gcal.service.ts:107) as BadRequestException (HTTP 400) when findCredentialByTypeAndUserId('google_calendar', userId) returns null — no Google Calendar credential stored for the user. Semantic mismatch like error 360: a 'not found' condition reported as 400. Reached via the google_calendar 'check' endpoint.
Source
Thrown at apps/api/v2/src/platform/calendars/services/gcal.service.ts:107
if (!app) {
throw new NotFoundException();
}
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 };View on GitHub (pinned to 176037d0af)
Solutions
- Complete the Google OAuth flow first: connect (get authUrl) → user authorizes → save (callback) → then check.
- Confirm the credential row exists: SELECT id FROM "Credential" WHERE type='google_calendar' AND "userId"=<id>.
- If invalid=true (error 377), re-run the OAuth flow.
Example fix
// before: checking before OAuth completes
await api.get('/v2/calendars/google_calendar/check'); // 400
// after: complete connect → save → check
const { data } = await api.post('/v2/calendars/google_calendar/connect', {});
// user visits data.authUrl, authorizes, returns with ?code=
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
// Confirm a google credential exists before calling check
const { data } = await api.get('/v2/calendars');
const hasGoogle = data.connectedCalendars.some(c => c.integration?.type === 'google_calendar');
if (!hasGoogle) {
// route the user to OAuth connect instead of calling check
return redirectToGoogleConnect();
} Type guard
function hasGoogleCredential(list) {
return Array.isArray(list) && list.some(c => c?.integration?.type === 'google_calendar');
} Try / catch
try {
await api.get('/v2/calendars/google_calendar/check');
} catch (e) {
if (e.response?.status === 400 && /not found/i.test(e.response?.data?.message)) {
// not yet connected — start OAuth rather than retry
return startGoogleOAuth();
}
throw e;
} Prevention
- Complete connect → save before calling check.
- Treat 400 'Credentials ... not found' as a connect prompt, not a transient retry.
- Clear any client-side 'connected' state on disconnect.
When it happens
Trigger: Calling check for google_calendar before completing the OAuth connect→save flow; user never authorized Google; credential was disconnected/deleted.
Common situations: OAuth callback not yet processed; onboarding polling check before save completes; user revoked and the credential row was removed.
Related errors
- Google Calendar is not connected for this user
- No valid credentials available for Google Calendar
- Google Calendar credentials are invalid. Please reconnect.
- Calendar credentials are invalid. Please reconnect.
- Credentials for apple calendar not found.
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/d49c7306657feb94.
Report an issue: GitHub.