calcom/cal.diy · error · NotFoundException

Failed to update event

Error message

Failed to update event

What it means

Thrown by updateEventWithClient when calendar.events.patch resolves with no data. The message string says 'Failed to update event' and is mapped to NotFoundException (HTTP 404) — note the status code does not match the failure semantics: an empty patch response usually indicates the event/calendarId combo was not found rather than a not-permitted update. The catch block also routes Google 404s here.

Source

Thrown at apps/api/v2/src/modules/cal-unified-calendars/services/google-calendar.service.ts:314

    }
  }

  private async updateEventWithClient(
    calendar: calendar_v3.Calendar,
    calendarId: string,
    eventId: string,
    updateData: UpdateUnifiedCalendarEventInput
  ): Promise<GoogleCalendarEventResponse> {
    const effectiveCalendarId = calendarId || "primary";
    const updatePayload = new GoogleCalendarEventInputPipe().transform(updateData);
    try {
      const event = await calendar.events.patch({
        calendarId: effectiveCalendarId,
        eventId,
        requestBody: updatePayload,
      });
      if (!event.data) {
        throw new NotFoundException("Failed to update event");
      }
      return event.data as GoogleCalendarEventResponse;
    } catch (error) {
      if (error instanceof HttpException) throw error;
      throw this.mapGoogleApiError(error, "Failed to update event details");
    }
  }

  private async deleteEventWithClient(
    calendar: calendar_v3.Calendar,
    calendarId: string,
    eventId: string
  ): Promise<void> {
    const effectiveCalendarId = calendarId || "primary";
    try {
      await calendar.events.delete({
        calendarId: effectiveCalendarId,
        eventId,

View on GitHub (pinned to 176037d0af)

Solutions

  1. Re-fetch the event to confirm it still exists before patching.
  2. Use the instance id (not master id) for recurring event updates.
  3. If the event was deleted, abandon the update and surface 'event no longer exists' to the user.
  4. Consider switching the exception type to BadRequestException or InternalServerErrorException to better match 'patch returned no data' semantics.

Example fix

// before
const event = await calendar.events.patch({ calendarId, eventId, requestBody: updatePayload });
if (!event.data) {
  throw new NotFoundException('Failed to update event');
}

// after: distinguish not-found from empty-response
if (!event.data) {
  this.logger.warn('Patch returned no data', { calendarId, eventId });
  throw new NotFoundException(`Event ${eventId} not found in calendar ${calendarId}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight existence check before patching (trades one extra call for clarity).
async function eventExistsForPatch(googleCalendarService: GoogleCalendarService, userId: number, credId: number, calId: string, evId: string): Promise<boolean> {
  try {
    await googleCalendarService.getEventByConnectionId(userId, credId, calId, evId);
    return true;
  } catch (e) {
    if (e instanceof NotFoundException) return false;
    throw e;
  }
}

Type guard

function isPatchSuccess(r: { data?: unknown }): r is { data: Record<string, unknown> } {
  return Boolean(r.data && typeof r.data === 'object');
}

Try / catch

try {
  return await googleCalendarService.updateEventByConnectionId(userId, credId, calId, evId, updateData);
} catch (e) {
  if (e instanceof NotFoundException && /update event/i.test(e.message)) {
    // event no longer exists — abandon update
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling PATCH /v2/calendars/connections/{id}/events/{eventId} with an eventId that does not exist in the calendarId, or a calendarId that does not exist. The patch target must resolve before any field is applied.

Common situations: Event deleted between read and update (TOCTOU); client sent the recurring-event master id but the calendar only has instances; calendarId typo; event migrated to another calendar.

Related errors


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