{"record":{"id":"fc15aa4375c0b6ca","repo":"calcom/cal.diy","slug":"no-selectedcalendar-found","errorCode":null,"errorMessage":"No SelectedCalendar found.","messagePattern":"No SelectedCalendar found\\.","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"warning","filePath":"apps/api/v2/src/modules/selected-calendars/services/selected-calendars.service.ts","lineNumber":58,"sourceCode":"    selectedCalendar: SelectedCalendarsQueryParamsInputDto,\n    user: UserWithProfile\n  ) {\n    const { integration, externalId, credentialId } = selectedCalendar;\n    await this.calendarsService.checkCalendarCredentials(Number(credentialId), user.id);\n\n    try {\n      const removedCalendarEntry = await this.selectedCalendarsRepository.removeUserSelectedCalendar(\n        user.id,\n        integration,\n        externalId,\n        undefined\n      );\n      await this.calendarsCacheService.deleteConnectedAndDestinationCalendarsCache(user.id);\n      return removedCalendarEntry;\n    } catch (error) {\n      if (error instanceof Error) {\n        if (error.message === NO_SELECTED_CALENDAR_FOUND) {\n          throw new NotFoundException(NO_SELECTED_CALENDAR_FOUND);\n        } else if (error.message === MULTIPLE_SELECTED_CALENDARS_FOUND) {\n          throw new BadRequestException(MULTIPLE_SELECTED_CALENDARS_FOUND);\n        } else {\n          throw new InternalServerErrorException(error.message);\n        }\n      }\n      throw new InternalServerErrorException(\n        \"An unexpected error occurred while deleting the selected calendar\"\n      );\n    }\n  }\n}\n","sourceCodeStart":40,"sourceCodeEnd":71,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/selected-calendars/services/selected-calendars.service.ts#L40-L71","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait api.delete(`/selected-calendars/${integration}/${externalId}`);\n// after — idempotent removal\ntry {\n  await api.delete(`/selected-calendars/${integration}/${externalId}`);\n} catch (e) {\n  if (e.status !== 404) throw e; // already gone is fine\n}","handlingStrategy":"try-catch","validationCode":"async function removeCalendarIdempotent(userId: number, integration: string, externalId: string) {\n  const list = await api.get('/selected-calendars', { params: { userId } });\n  const exists = list.some((c: { integration: string; externalId: string }) =>\n    c.integration === integration && c.externalId === externalId);\n  if (!exists) return; // already gone\n  return api.delete(`/selected-calendars/${integration}/${externalId}`);\n}","typeGuard":"const isExistingCalendar = (list: { integration: string; externalId: string }[], integration: string, externalId: string): boolean =>\n  list.some(c => c.integration === integration && c.externalId === externalId);","tryCatchPattern":"try { await api.delete(`/selected-calendars/${integration}/${externalId}`); }\ncatch (e) { if (e.status !== 404) throw e; /* already removed — ok */ }","preventionTips":["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."],"tags":["selected-calendars","not-found","nestjs","idempotency"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}