{"record":{"id":"58e54c3747c6fbed","repo":"calcom/cal.diy","slug":"no-calendar-id-provided-in-deleteevent","errorCode":null,"errorMessage":"no calendar id provided in deleteEvent","messagePattern":"no calendar id provided in deleteEvent","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-store/feishucalendar/lib/CalendarService.ts","lineNumber":261,"sourceCode":"      this.log.error(error);\n      await this.deleteEvent(eventId, event);\n      throw error;\n    }\n  }\n\n  /**\n   * @param uid\n   * @param event\n   * @returns\n   */\n  async deleteEvent(uid: string, event: CalendarEvent, externalCalendarId?: string) {\n    const mainHostDestinationCalendar = event.destinationCalendar?.find(\n      (cal) => cal.externalId === externalCalendarId\n    );\n    const calendarId = externalCalendarId || mainHostDestinationCalendar?.externalId;\n    if (!calendarId) {\n      this.log.error(\"no calendar id provided in deleteEvent\");\n      throw new Error(\"no calendar id provided in deleteEvent\");\n    }\n    try {\n      const response = await this.fetcher(`/calendar/v4/calendars/${calendarId}/events/${uid}`, {\n        method: \"DELETE\",\n      });\n      await handleFeishuError(response, this.log);\n    } catch (error) {\n      this.log.error(error);\n      throw error;\n    }\n  }\n\n  async getAvailability(params: GetAvailabilityParams): Promise<EventBusyDate[]> {\n    const { dateFrom, dateTo, selectedCalendars } = params;\n    const selectedCalendarIds = selectedCalendars\n      .filter((e) => e.integration === this.integrationName)\n      .map((e) => e.externalId)\n      .filter(Boolean);","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/packages/app-store/feishucalendar/lib/CalendarService.ts#L243-L279","documentation":"Thrown by FeishuCalendarService.deleteEvent when neither externalCalendarId nor a matching destinationCalendar.externalId is present. deleteEvent is invoked from booking cancellation AND as a rollback path inside createEvent/updateEvent, so this error can compound during failed creates/updates.","triggerScenarios":"Cancelling a booking whose Feishu calendar id was never stored, or rolling back a createEvent/updateEvent where externalCalendarId is not threaded through. event.destinationCalendar undefined or has no entry matching externalCalendarId.","commonSituations":"Booking created before destinationCalendar was set; reference booking.externalCalendarId not passed; destinationCalendar removed by user after booking creation; rollback after error 556/557.","solutions":["Thread externalCalendarId from the booking reference into every deleteEvent call.","Persist the Feishu event's calendar id at creation time so cancellation can target it.","Make deleteEvent idempotent: treat missing calendar id as 'nothing to delete' and return rather than throw, since deletion is best-effort during rollback.","Log the booking uid so operators can manually clean orphan Feishu events."],"exampleFix":"// before\nconst calendarId = externalCalendarId || mainHostDestinationCalendar?.externalId;\nif (!calendarId) {\n  this.log.error(\"no calendar id provided in deleteEvent\");\n  throw new Error(\"no calendar id provided in deleteEvent\");\n}\n\n// after - best-effort delete during rollback\nif (!calendarId) {\n  this.log.warn(`Skipping Feishu deleteEvent for ${uid}: no calendar id available (likely never created).`);\n  return;\n}","handlingStrategy":"validation","validationCode":"if (!externalCalendarId && !event.destinationCalendar?.some((c) => c.externalId)) {\n  this.log.warn(`deleteEvent for ${uid} has no calendar id; skipping.`);\n  return;\n}","typeGuard":"const hasDeleteTarget = (event: CalendarEvent, externalCalendarId?: string): boolean =>\n  typeof externalCalendarId === \"string\" && externalCalendarId.length > 0 ||\n  (Array.isArray(event.destinationCalendar) && event.destinationCalendar.some((c) => typeof c.externalId === \"string\" && c.externalId.length > 0));","tryCatchPattern":"// make deleteEvent best-effort during rollback\nif (!calendarId) {\n  this.log.warn(`Skipping Feishu deleteEvent for ${uid}: no calendar id.`);\n  return;\n}","preventionTips":["Make deleteEvent idempotent: a missing calendar id is a no-op, not an error, during rollback.","Persist the Feishu calendar id on the booking reference at creation time.","Log booking uid on skipped deletes so operators can clean orphan events."],"tags":["feishu","larksuite","calendar","delete-event","destination-calendar","rollback"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}