{"record":{"id":"b198046acf2720f2","repo":"calcom/cal.diy","slug":"could-not-find-calendar-externalid","errorCode":null,"errorMessage":"Could not find calendar ${externalId}","messagePattern":"Could not find calendar (.+?)","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"apps/api/v2/src/modules/destination-calendars/services/destination-calendars.service.ts","lineNumber":31,"sourceCode":"  ) {}\n\n  async updateDestinationCalendars(\n    integration: string,\n    externalId: string,\n    userId: number,\n    delegationCredentialId?: string\n  ) {\n    const userCalendars = await this.calendarsService.getCalendars(userId);\n    const allCalendars: Calendar[] = userCalendars.connectedCalendars\n      .map((cal: ConnectedCalendar) => cal.calendars ?? [])\n      .flat();\n    const credentialId = allCalendars.find(\n      (cal: Calendar) =>\n        cal.externalId === externalId && cal.integration === integration && cal.readOnly === false\n    )?.credentialId;\n\n    if (!delegationCredentialId && !credentialId) {\n      throw new NotFoundException(`Could not find calendar ${externalId}`);\n    }\n\n    const delegatedCalendar = delegationCredentialId\n      ? allCalendars.find(\n          (cal: Calendar) =>\n            cal.externalId === externalId &&\n            cal.integration === integration &&\n            cal.delegationCredentialId === delegationCredentialId\n        )\n      : undefined;\n\n    if (delegationCredentialId && !delegatedCalendar) {\n      throw new NotFoundException(`Could not find calendar ${externalId}`);\n    }\n\n    const primaryEmail = delegatedCalendar\n      ? (delegatedCalendar.primary && delegatedCalendar?.email) || undefined\n      : allCalendars.find((cal: Calendar) => cal.primary && cal.credentialId === credentialId)?.email;","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/destination-calendars/services/destination-calendars.service.ts#L13-L49","documentation":"Thrown by DestinationCalendarsService.updateCalendar when no delegationCredentialId is provided AND no matching calendar is found among the user's connected calendars for the given externalId+integration (with readOnly=false). The lookup runs getCalendars(userId) then searches for cal.externalId === externalId && cal.integration === integration && cal.readOnly === false to obtain credentialId; a miss raises NotFoundException (HTTP 404).","triggerScenarios":"PUT/PATCH to update a destination calendar with an externalId that the user does not own, that belongs to a different integration, that is read-only, or that no longer exists in the connected calendar list. Without delegationCredentialId, the credentialId search must succeed or this throws.","commonSituations":"externalId from a stale frontend cache; calendar renamed/moved on the provider side; integration mismatch (passing a Google calendar id for an Office365 integration); calendar is a read-only delegated calendar but delegationCredentialId was not passed.","solutions":["Re-fetch the user's connected calendars (GET /calendars) and pass a current externalId + matching integration.","If the target is a delegated calendar, pass the correct delegationCredentialId so the second lookup path is used instead.","Confirm the calendar is not read-only for the credential you expect to write with."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const userCalendars = await calendarsService.getCalendars(userId);\nconst all = userCalendars.connectedCalendars.flatMap(c => c.calendars ?? []);\nconst match = all.find(c => c.externalId === externalId && c.integration === integration && !c.readOnly);\nif (!match && !delegationCredentialId) {\n  throw new NotFoundException(`Could not find calendar ${externalId}`);\n}\nawait destinationCalendarsService.updateCalendar(userId, integration, externalId, delegationCredentialId);","typeGuard":"const isWritableCalendar = (c: Calendar): boolean =>\n  !!c.externalId && !!c.integration && c.readOnly === false;","tryCatchPattern":null,"preventionTips":["Refresh the calendar list before letting the user pick a destination.","Filter out read-only calendars in the picker.","Pass delegationCredentialId when operating on delegated calendars."],"tags":["destination-calendars","calendar","not-found","external-id","delegation"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}