calcom/cal.diy · error · NotFoundException

Failed to update meeting details

Error message

Failed to update meeting details

What it means

GoogleCalendarService.updateEventDetails wraps the calendar.events.patch call in try/catch and rethrows as NotFoundException('Failed to update meeting details'). Any error from the Google API during the patch (auth, validation, quota, 404) is collapsed into this single message, masking the real cause.

Source

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

      bookingReference.credential?.key,
      bookingReference.delegationCredential
    );

    const updatePayload = new GoogleCalendarEventInputPipe().transform(updateData);

    try {
      const event = await calendar.events.patch({
        calendarId: bookingReference?.externalCalendarId ?? "primary",
        eventId: bookingReference?.uid,
        requestBody: updatePayload,
      });

      if (!event.data) {
        throw new NotFoundException("Failed to update meeting");
      }
      return event.data as GoogleCalendarEventResponse;
    } catch (error) {
      throw new NotFoundException("Failed to update meeting details");
    }
  }

  /**
   * Gets an authorized Google Calendar instance
   * Tries delegation credentials first, falls back to direct OAuth
   */
  private async getAuthorizedCalendarInstance(
    userEmail?: string,
    oAuthCredentials?: Prisma.JsonValue | undefined,
    delegationCredential?: { id: string } | null
  ): Promise<calendar_v3.Calendar> {
    if (userEmail && delegationCredential?.id) {
      const delegatedCalendar = await this.getDelegatedCalendarInstance(delegationCredential, userEmail);
      if (delegatedCalendar) {
        return delegatedCalendar;
      }
    }

View on GitHub (pinned to 176037d0af)

Solutions

  1. Log the underlying error before rethrowing so the cause is diagnosable (today it is swallowed).
  2. Validate the patch payload with GoogleCalendarEventInputPipe output schema before sending.
  3. Re-authenticate the Google connection for 401/403; retry with backoff on 429/5xx.
  4. Improve the catch to distinguish 400 (bad payload) from 404 (gone) from 5xx (upstream).

Example fix

// before
} catch (error) {
  throw new NotFoundException("Failed to update meeting details");
}

// after
} catch (error) {
  this.logger.error({ message: 'gcal events.patch failed', eventId, error });
  const status = error?.code ?? error?.response?.status;
  if (status === 400) throw new BadRequestException('Invalid event update payload for Google Calendar');
  if (status === 401 || status === 403) throw new UnauthorizedException('Google Calendar access denied');
  if (status === 404) throw new NotFoundException('Meeting not found in Google Calendar');
  throw new BadGatewayException('Failed to update meeting in Google Calendar');
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate the patch payload against Google's schema before sending
const clean = stripUnknownFields(patch, ['summary','description','start','end','attendees','location']);
assertValidGoogleEventPatch(clean);

Try / catch

try {
  return await api.v2.calUnified.updateEvent(eventUid, patch);
} catch (err) {
  if (err?.statusCode === 404 && /Failed to update meeting details/i.test(err?.message)) {
    // ambiguous: could be auth, payload, quota, or upstream. Log + escalate; do NOT blindly retry.
    throw new Error('Update failed at Google Calendar; check credentials, payload, and quota.');
  }
  throw err;
}

Prevention

When it happens

Trigger: Google Calendar API rejects the patch: 400 invalid field values, 401/403 credential or scope problems, 404 event/calendar gone, 429 quota, 5xx transient.

Common situations: Patch payload violates Google's schema (e.g. invalid attendee email, bad timestamp); credential's refresh token expired; missing calendar.events scope; rate-limited.

Related errors


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