calcom/cal.diy · error · NotFoundException

Could not load booking details for uid=${existingBooking.uid

Error message

Could not load booking details for uid=${existingBooking.uid}

What it means

Thrown by handleIntegrationLocationUpdate when re-fetching the booking by its numeric ID (getBookingByIdWithUserAndEventDetails) fails the bookingHasUser type guard. That guard returns false when the re-fetched booking is null OR its user relation is null. The integration location handlers all require a host user (to read credentials and build the calendar event), so a missing user is fatal. It surfaces as HTTP 404 NotFoundException even though the root cause is usually a data-integrity gap rather than a wrong UID.

Source

Thrown at apps/api/v2/src/platform/bookings/2024-08-13/services/booking-location-integration.service.ts:86

    inputLocation: { type: "integration"; integration: Integration_2024_08_13 },
    user: ApiAuthGuardUser,
    existingBookingHost: { organizationId: number | null } | null
  ): Promise<BookingLocationResponse> {
    if (!existingBookingHost) {
      throw new NotFoundException(`No user found for booking with uid=${existingBooking.uid}`);
    }

    const integrationSlug = inputLocation.integration;
    const internalLocation =
      apiToInternalintegrationsMapping[integrationSlug as keyof typeof apiToInternalintegrationsMapping];

    if (!internalLocation) {
      throw new BadRequestException(`Unsupported integration: ${integrationSlug}`);
    }

    const booking = await this.bookingsRepository.getBookingByIdWithUserAndEventDetails(existingBooking.id);
    if (!bookingHasUser(booking)) {
      throw new NotFoundException(`Could not load booking details for uid=${existingBooking.uid}`);
    }

    const ctx: IntegrationHandlerContext = {
      existingBooking,
      booking,
      integrationSlug,
      internalLocation,
      user,
      existingBookingHost,
      inputLocation,
    };

    switch (integrationSlug) {
      case "google-meet":
        return this.handleGoogleMeetLocation(ctx);
      case "office365-video":
        return this.handleMSTeamsLocation(ctx);
      case "cal-video":

View on GitHub (pinned to 176037d0af)

Solutions

  1. GET the booking first and confirm it has a non-null user/owner before sending the integration PATCH.
  2. If the booking is orphaned, reassign booking.userId to a valid user via the DB/admin tooling, then retry.
  3. Verify the booking UID is correct and that the booking has not been deleted between the GET and the PATCH.
  4. If reproducing in tests, create the booking through the normal booking flow so a user is always attached.

Example fix

// before: PATCH /v2/bookings/{uid}/location with location.type=integration on an orphaned booking
// after: verify host user exists before updating
const booking = await api.get(`/v2/bookings/${uid}`);
if (!booking.user) {
  // reassign or skip integration update; booking has no host to source credentials from
  throw new Error(`Booking ${uid} has no host user; cannot set integration location`);
}
await api.patch(`/v2/bookings/${uid}/location`, { location: { type: 'integration', integration: 'zoom' } });
Defensive patterns

Strategy: validation

Validate before calling

// Before PATCHing location to an integration, confirm the booking has a host user.
const booking = await api.get(`/v2/bookings/${uid}`);
if (!booking) throw new Error(`Booking ${uid} not found`);
if (!booking.user) throw new Error(`Booking ${uid} has no host user; cannot use integration location`);

Type guard

function bookingHasHostUser(b: { user: unknown } | null | undefined): b is { user: Record<string, unknown> } {
  return !!b && !!b.user && typeof b.user === 'object';
}

Try / catch

try {
  await api.patch(`/v2/bookings/${uid}/location`, { location: { type: 'integration', integration } });
} catch (err) {
  if (err.status === 404 && /Could not load booking details/.test(err.message)) {
    // booking has no host user; reassign owner or fall back to a non-integration location
  }
  throw err;
}

Prevention

When it happens

Trigger: PATCH /v2/bookings/{uid} (or the 2024-08-13 equivalent) with body location.type = "integration" (e.g. zoom, google-meet, cal-video) for a booking row whose user relation is null, or for a booking that gets deleted between the initial UID lookup and the ID re-fetch inside handleIntegrationLocationUpdate.

Common situations: Orphaned/legacy bookings where userId is set but the user record was deleted; bookings created by background jobs without an owner; race condition where the booking is cancelled/deleted mid-request; seeded test data without a linked user.

Related errors


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