calcom/cal.diy · error · BadRequestException
Credentials for apple calendar not found.
Error message
Credentials for apple calendar not found.
What it means
Thrown by AppleCalendarService.checkIfCalendarConnected (apple-calendar.service.ts:39) as a NestJS BadRequestException (HTTP 400) when findCredentialByTypeAndUserId(APPLE_CALENDAR_TYPE, userId) returns null — no Apple Calendar credential row exists for the user. Reached via the calendars 'check' endpoint (calendar = apple_calendar). Note the semantic mismatch: a 'not found' condition is reported as 400 rather than 404.
Source
Thrown at apps/api/v2/src/platform/calendars/services/apple-calendar.service.ts:39
userEmail: string,
username: string,
password: string
): Promise<{ status: string }> {
return await this.saveCalendarCredentials(userId, userEmail, username, password);
}
async check(userId: number): Promise<{ status: typeof SUCCESS_STATUS }> {
return await this.checkIfCalendarConnected(userId);
}
async checkIfCalendarConnected(userId: number): Promise<{ status: typeof SUCCESS_STATUS }> {
const appleCalendarCredentials = await this.credentialRepository.findCredentialByTypeAndUserId(
APPLE_CALENDAR_TYPE,
userId
);
if (!appleCalendarCredentials) {
throw new BadRequestException("Credentials for apple calendar not found.");
}
if (appleCalendarCredentials.invalid) {
throw new BadRequestException("Invalid apple calendar credentials.");
}
const { connectedCalendars } = await this.calendarsService.getCalendars(userId);
const appleCalendar = connectedCalendars.find(
(cal: { integration: { type: string } }) => cal.integration.type === APPLE_CALENDAR_TYPE
);
if (!appleCalendar) {
throw new UnauthorizedException("Apple calendar not connected.");
}
if (appleCalendar.error?.message) {
throw new UnauthorizedException(appleCalendar.error?.message);
}
return {View on GitHub (pinned to 176037d0af)
Solutions
- Call the Apple Calendar 'save' endpoint (POST /v2/calendars/apple_calendar/save) with a valid username + app-specific password first, then call 'check'.
- Verify the credential row exists: SELECT id, "invalid" FROM "Credential" WHERE type='apple_calendar' AND "userId"=<id>.
- If the row was deleted unintentionally, re-run save; if it exists but invalid=true, see error 361.
Example fix
// before: calling check on a fresh user
await api.get('/v2/calendars/apple_calendar/check'); // 400
// after: save first, then check
await api.post('/v2/calendars/apple_calendar/save', { username, password });
await api.get('/v2/calendars/apple_calendar/check'); // 200 Defensive patterns
Strategy: validation
Validate before calling
// Run before calling /v2/calendars/apple_calendar/check
async function hasAppleCredential(api, userId) {
const { data } = await api.get('/v2/calendars');
return data.connectedCalendars.some(c => c.integration?.type === 'apple_calendar');
}
if (!(await hasAppleCredential(api, userId))) {
throw new ClientError('Connect Apple Calendar (save) before checking.');
} Type guard
// Narrow a connected-calendars payload to the apple entry
function isAppleConnected(list) {
return Array.isArray(list) && list.some(
(c) => c?.integration?.type === 'apple_calendar' && !c?.error
);
} Try / catch
try {
await api.get('/v2/calendars/apple_calendar/check');
} catch (e) {
if (e.response?.status === 400 && /not found/i.test(e.response?.data?.message)) {
// Not connected yet — route the user to the save flow rather than retrying.
return redirectToAppleSave();
}
throw e;
} Prevention
- Always call 'save' before 'check' in onboarding flows.
- Treat a 400 'Credentials ... not found' as a connect prompt, not a transient retry.
- Seed test users with an apple_calendar Credential row when writing e2e tests.
When it happens
Trigger: Calling GET/POST /v2/calendars/apple_calendar/check for a user who never completed the 'save' step; calling check after the credential was disconnected/deleted; a seeded test user with no apple_calendar Credential row.
Common situations: Onboarding UI polling 'check' before 'save' finishes; test fixtures that create a User but omit Credentials; a previously disconnected calendar whose status is still being polled.
Related errors
- Google Calendar is not connected for this user
- Invalid apple calendar credentials.
- Credentials for google_calendar not found.
- No valid credentials available for Google Calendar
- Google Calendar credentials are invalid. Please reconnect.
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/8ae19fb27dfe555d.
Report an issue: GitHub.