calcom/cal.diy · error · NotFoundException

Slot with uid=${uid} not found

Error message

Slot with uid=${uid} not found

What it means

Thrown by SlotsService.updateReservedSlot when PATCHing a reservation slot whose uid does not exist in the slots table. The service calls slotsRepository.getByUid(uid) and, on a null result, throws 404 NotFound. Slot reservations are temporary rows with a reservationDuration TTL, so a uid can disappear between reserve and update.

Source

Thrown at apps/api/v2/src/modules/slots/slots-2024-09-04/services/slots.service.ts:274

      return false;
    }
    const orgMembership = await this.membershipsRepository.findMembershipByTeamId(team.parentId, authUserId);
    const hasAcceptedOrgMembership = !!orgMembership?.accepted;
    return hasAcceptedOrgMembership;
  }

  async getReservedSlot(uid: string) {
    const slot = await this.slotsRepository.getByUid(uid);
    if (!slot) {
      return null;
    }
    return this.slotsOutputService.getReservationSlot(slot);
  }

  async updateReservedSlot(input: ReserveSlotInput_2024_09_04, uid: string) {
    const dbSlot = await this.slotsRepository.getByUid(uid);
    if (!dbSlot) {
      throw new NotFoundException(`Slot with uid=${uid} not found`);
    }

    const eventType = await this.eventTypeRepository.getEventTypeWithHosts(input.eventTypeId);
    if (!eventType) {
      throw new NotFoundException(`Event Type with ID=${input.eventTypeId} not found`);
    }

    const startDate = DateTime.fromISO(input.slotStart, { zone: "utc" });
    if (!startDate.isValid) {
      throw new BadRequestException("Invalid start date");
    }

    if (input.slotDuration) {
      this.validateSlotDuration(eventType, input.slotDuration);
    }

    const endDate = startDate.plus({ minutes: input.slotDuration ?? eventType.length });
    if (!endDate.isValid) {

View on GitHub (pinned to 176037d0af)

Solutions

  1. Reserve a fresh slot with POST /v2/event-types/{eventTypeId}/slots and use the returned uid for the update.
  2. GET the slot by uid before PATCHing; if it 404s, re-reserve.
  3. Increase reservationDuration when creating the slot to give the user more time to confirm.

Example fix

// before
await api.patchSlot(staleUid, body);

// after
const fresh = await api.reserveSlot({ eventTypeId, slotStart, reservationDuration: 15 });
await api.patchSlot(fresh.uid, { ...body, eventTypeId, slotStart });
Defensive patterns

Strategy: validation

Validate before calling

async function getEditableSlot(api, uid: string) {
  const slot = await api.getReservedSlot(uid).catch(() => null);
  if (!slot) return null; // caller should re-reserve
  return slot;
}

// usage before PATCH:
// const slot = await getEditableSlot(api, uid);
// if (!slot) { const fresh = await api.reserveSlot(...); uid = fresh.uid; }

Type guard

function isLiveReservation(
  slot: { uid: string; expiresAt?: string } | null
): slot is { uid: string } {
  return !!slot && (!slot.expiresAt || new Date(slot.expiresAt) > new Date());
}

Try / catch

try {
  return await api.updateReservedSlot(uid, body);
} catch (e) {
  if (e.status === 404 && /Slot with uid=/.test(e.message)) {
    const fresh = await api.reserveSlot({ eventTypeId, slotStart });
    return api.updateReservedSlot(fresh.uid, { ...body, slotStart });
  }
  throw e;
}

Prevention

When it happens

Trigger: PATCH /v2/slots/{uid} (or the slots-2024-09-04 update endpoint) with a uid that was never created, has already expired past its reservationDuration (default DEFAULT_RESERVATION_DURATION), was converted into a booking, or belongs to a different environment.

Common situations: The reservation expired before the user confirmed (short reservationDuration). The uid was copied from a staging environment into production. The slot was already turned into a booking and the reservation row removed. A typo or truncation in the uid.

Related errors


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