calcom/cal.diy · error · Error

no calendar id provided in deleteEvent

Error message

no calendar id provided in deleteEvent

What it means

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.

Source

Thrown at packages/app-store/feishucalendar/lib/CalendarService.ts:261

      this.log.error(error);
      await this.deleteEvent(eventId, event);
      throw error;
    }
  }

  /**
   * @param uid
   * @param event
   * @returns
   */
  async deleteEvent(uid: string, event: CalendarEvent, externalCalendarId?: string) {
    const mainHostDestinationCalendar = event.destinationCalendar?.find(
      (cal) => cal.externalId === externalCalendarId
    );
    const calendarId = externalCalendarId || mainHostDestinationCalendar?.externalId;
    if (!calendarId) {
      this.log.error("no calendar id provided in deleteEvent");
      throw new Error("no calendar id provided in deleteEvent");
    }
    try {
      const response = await this.fetcher(`/calendar/v4/calendars/${calendarId}/events/${uid}`, {
        method: "DELETE",
      });
      await handleFeishuError(response, this.log);
    } catch (error) {
      this.log.error(error);
      throw error;
    }
  }

  async getAvailability(params: GetAvailabilityParams): Promise<EventBusyDate[]> {
    const { dateFrom, dateTo, selectedCalendars } = params;
    const selectedCalendarIds = selectedCalendars
      .filter((e) => e.integration === this.integrationName)
      .map((e) => e.externalId)
      .filter(Boolean);

View on GitHub (pinned to 176037d0af)

Solutions

  1. Thread externalCalendarId from the booking reference into every deleteEvent call.
  2. Persist the Feishu event's calendar id at creation time so cancellation can target it.
  3. Make deleteEvent idempotent: treat missing calendar id as 'nothing to delete' and return rather than throw, since deletion is best-effort during rollback.
  4. Log the booking uid so operators can manually clean orphan Feishu events.

Example fix

// before
const calendarId = externalCalendarId || mainHostDestinationCalendar?.externalId;
if (!calendarId) {
  this.log.error("no calendar id provided in deleteEvent");
  throw new Error("no calendar id provided in deleteEvent");
}

// after - best-effort delete during rollback
if (!calendarId) {
  this.log.warn(`Skipping Feishu deleteEvent for ${uid}: no calendar id available (likely never created).`);
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

if (!externalCalendarId && !event.destinationCalendar?.some((c) => c.externalId)) {
  this.log.warn(`deleteEvent for ${uid} has no calendar id; skipping.`);
  return;
}

Type guard

const hasDeleteTarget = (event: CalendarEvent, externalCalendarId?: string): boolean =>
  typeof externalCalendarId === "string" && externalCalendarId.length > 0 ||
  (Array.isArray(event.destinationCalendar) && event.destinationCalendar.some((c) => typeof c.externalId === "string" && c.externalId.length > 0));

Try / catch

// make deleteEvent best-effort during rollback
if (!calendarId) {
  this.log.warn(`Skipping Feishu deleteEvent for ${uid}: no calendar id.`);
  return;
}

Prevention

When it happens

Trigger: 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.

Common situations: Booking created before destinationCalendar was set; reference booking.externalCalendarId not passed; destinationCalendar removed by user after booking creation; rollback after error 556/557.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/58e54c3747c6fbed. Report an issue: GitHub.