calcom/cal.diy · warning · NotFoundException
No SelectedCalendar found.
Error message
No SelectedCalendar found.
What it means
NotFoundException (HTTP 404) thrown by SelectedCalendarsService when deleting a user selected calendar and the underlying repository reports NO_SELECTED_CALENDAR_FOUND. The repository's removeUserSelectedCalendar raises this when no row matches the (userId, integration, externalId) tuple, and the service translates the string message into a 404.
Source
Thrown at apps/api/v2/src/modules/selected-calendars/services/selected-calendars.service.ts:58
selectedCalendar: SelectedCalendarsQueryParamsInputDto,
user: UserWithProfile
) {
const { integration, externalId, credentialId } = selectedCalendar;
await this.calendarsService.checkCalendarCredentials(Number(credentialId), user.id);
try {
const removedCalendarEntry = await this.selectedCalendarsRepository.removeUserSelectedCalendar(
user.id,
integration,
externalId,
undefined
);
await this.calendarsCacheService.deleteConnectedAndDestinationCalendarsCache(user.id);
return removedCalendarEntry;
} catch (error) {
if (error instanceof Error) {
if (error.message === NO_SELECTED_CALENDAR_FOUND) {
throw new NotFoundException(NO_SELECTED_CALENDAR_FOUND);
} else if (error.message === MULTIPLE_SELECTED_CALENDARS_FOUND) {
throw new BadRequestException(MULTIPLE_SELECTED_CALENDARS_FOUND);
} else {
throw new InternalServerErrorException(error.message);
}
}
throw new InternalServerErrorException(
"An unexpected error occurred while deleting the selected calendar"
);
}
}
}
View on GitHub (pinned to 176037d0af)
Solutions
- Before deleting, confirm the calendar still appears in GET /v2/selected-calendars for the user.
- Treat a 404 on delete as a success if your goal is simply 'ensure it is gone' (idempotent delete).
- Verify the integration key and externalId exactly match the values returned by the list endpoint.
Example fix
// before
await api.delete(`/selected-calendars/${integration}/${externalId}`);
// after — idempotent removal
try {
await api.delete(`/selected-calendars/${integration}/${externalId}`);
} catch (e) {
if (e.status !== 404) throw e; // already gone is fine
} Defensive patterns
Strategy: try-catch
Validate before calling
async function removeCalendarIdempotent(userId: number, integration: string, externalId: string) {
const list = await api.get('/selected-calendars', { params: { userId } });
const exists = list.some((c: { integration: string; externalId: string }) =>
c.integration === integration && c.externalId === externalId);
if (!exists) return; // already gone
return api.delete(`/selected-calendars/${integration}/${externalId}`);
} Type guard
const isExistingCalendar = (list: { integration: string; externalId: string }[], integration: string, externalId: string): boolean =>
list.some(c => c.integration === integration && c.externalId === externalId); Try / catch
try { await api.delete(`/selected-calendars/${integration}/${externalId}`); }
catch (e) { if (e.status !== 404) throw e; /* already removed — ok */ } Prevention
- Treat 404 on delete as success (idempotent removal).
- Verify integration key and externalId against the list endpoint before deleting.
- Refresh the calendar list after external disconnect webhooks so stale entries are not deleted again.
When it happens
Trigger: DELETE /v2/selected-calendars with an integration+externalId pair that the user never connected, or already removed; a sync process trying to remove a calendar that was deleted by another client in the meantime.
Common situations: Stale UI list still showing a calendar the user disconnected elsewhere; webhook firing twice for the same calendar removal; integration name mismatch (e.g. 'google_calendar' vs 'google') or externalId drift after re-auth.
Related errors
- Deleted link not found
- Event type with ID=${eventTypeId} does not exist.
- Team with id ${teamId} not found
- Event type with id ${eventTypeId} not found
- Payment with uid ${uid} not found
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/fc15aa4375c0b6ca.
Report an issue: GitHub.