{"record":{"id":"cdb7122d4d06fe72","repo":"calcom/cal.diy","slug":"multiple-selectecalendars-found-skipping-deletion","errorCode":null,"errorMessage":"Multiple SelecteCalendars found. Skipping deletion","messagePattern":"Multiple SelecteCalendars found\\. Skipping deletion","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/modules/selected-calendars/services/selected-calendars.service.ts","lineNumber":60,"sourceCode":"  ) {\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":42,"sourceCodeEnd":71,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/selected-calendars/services/selected-calendars.service.ts#L42-L71","documentation":"BadRequestException (HTTP 400) thrown when the repository reports MULTIPLE_SELECTED_CALENDARS_FOUND during deletion. removeUserSelectedCalendar expects to remove exactly one row; finding two or more rows for the same (userId, integration, externalId) is an inconsistent state, so the service refuses to delete ambiguously rather than guessing which row.","triggerScenarios":"DELETE /v2/selected-calendars when the database contains duplicate SelectedCalendar rows for the same user/integration/externalId — typically from a past bug, a missing unique constraint, or a non-atomic upsert that inserted twice.","commonSituations":"Legacy data created before a unique constraint was added; concurrent connect flows racing to insert the same calendar; a manual DB import that duplicated rows.","solutions":["Investigate and deduplicate the rows in the database (keep one, delete the rest) so deletion is unambiguous.","Add a unique constraint on (userId, integration, externalId) if missing, to prevent recurrence.","Temporarily delete by id or with a bulk delete to clear the duplicates, then retry the normal endpoint."],"exampleFix":"// before — normal delete fails on duplicates\nawait api.delete(`/selected-calendars/${integration}/${externalId}`); // 400\n// after — dedupe via admin/DB, then retry\n// SQL: DELETE FROM \"SelectedCalendar\" WHERE id IN (SELECT id FROM ... GROUP BY ... HAVING COUNT(*)>1);\nawait api.delete(`/selected-calendars/${integration}/${externalId}`);","handlingStrategy":"validation","validationCode":"async function assertSingleCalendarRow(userId: number, integration: string, externalId: string) {\n  const rows = await api.get('/selected-calendars', { params: { userId, integration, externalId } });\n  if (rows.length > 1) throw new Error(`Duplicate rows (${rows.length}); dedupe before deleting`);\n}","typeGuard":"const hasUniqueCalendars = (rows: { integration: string; externalId: string }[]): boolean => {\n  const seen = new Set<string>();\n  return rows.every(r => { const k = `${r.integration}:${r.externalId}`; if (seen.has(k)) return false; seen.add(k); return true; });\n};","tryCatchPattern":"try { await api.delete(`/selected-calendars/${integration}/${externalId}`); }\ncatch (e) { if (/multiple selectedcalendars/i.test(e.message)) { /* run dedupe, then retry */ } else throw e; }","preventionTips":["Add a unique constraint on (userId, integration, externalId) to prevent duplicate rows.","Periodically audit for duplicate SelectedCalendar rows.","Use upsert (not insert) when connecting calendars."],"tags":["selected-calendars","data-integrity","duplicate","nestjs"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}