calcom/cal.diy · error · BadRequestException

Please provide booking uid instead of booking id.

Error message

Please provide booking uid instead of booking id.

What it means

cancelBooking computes isUidNumber = !Number.isNaN(Number(bookingUid)); if the route param parses as a number it throws BadRequestException (HTTP 400) telling the caller to send a booking uid, not a numeric booking id. Booking uids are string identifiers; numeric ids are a different column.

Solutions

  1. Use booking.uid (string), not booking.id (number), in the cancel path.
  2. Audit response mapping to surface uid as the canonical identifier.
  3. Add a client-side guard: if /^\d+$/.test(bookingUid) reject before sending.

Example fix

// before
await api.cancelBooking(String(booking.id));
// after
await api.cancelBooking(booking.uid);
Defensive patterns

Strategy: validation

Validate before calling

function assertBookingUid(uid: string) {
  if (typeof uid !== 'string' || /^\d+$/.test(uid)) {
    throw new Error('Provide booking.uid (string), not booking.id (numeric)');
  }
}
assertBookingUid(bookingUid);

Type guard

const isBookingUidNotNumericId = (v: unknown): v is string =>
  typeof v === 'string' && v.length > 0 && !/^\d+$/.test(v);

Try / catch

try { await api.cancelBooking(uid); }
catch (e) {
  if (e.status === 400 && /booking uid instead of booking id/.test(e.message)) {
    // re-resolve uid from booking object and retry
  } else throw e;
}

Prevention

When it happens

Trigger: POST /:bookingUid/cancel where :bookingUid is purely numeric (e.g. '12345' — the booking id) instead of the uid string (e.g. 'a1b2c3...').

Common situations: Client used booking.id from a response instead of booking.uid; UI label confusion; migration from an older API that used numeric ids.

Related errors


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

Appendix: source

Thrown at apps/api/v2/src/platform/bookings/2024-04-15/controllers/bookings.controller.ts:246

    } catch (err) {
      this.handleBookingErrors(err);
    }
    throw new InternalServerErrorException("Could not create booking.");
  }

  @Post("/:bookingUid/cancel")
  async cancelBooking(
    @Req() req: BookingRequest,
    @Param("bookingUid") bookingUid: string,
    @Body() _body: CancelBookingInput_2024_04_15,
    @Headers(X_CAL_CLIENT_ID) clientId?: string,
    @Headers(X_CAL_PLATFORM_EMBED) isEmbed?: string
  ): Promise<ApiResponse<{ bookingId: number; bookingUid: string; onlyRemovedAttendee: boolean }>> {
    const oAuthClientId = clientId?.toString();
    const isUidNumber = !Number.isNaN(Number(bookingUid));

    if (isUidNumber) {
      throw new BadRequestException("Please provide booking uid instead of booking id.");
    }

    if (bookingUid) {
      const { bookingInfo } = await getBookingInfo(bookingUid);
      if (!bookingInfo) {
        throw new NotFoundException(`Booking with UID=${bookingUid} does not exist.`);
      }
      if (bookingInfo.status === "CANCELLED") {
        throw new BadRequestException(
          `Can't cancel booking with uid=${bookingUid} because it has been cancelled already. Please provide uid of a booking that is not cancelled.`
        );
      }
      try {
        req.body.uid = bookingUid;
        const bookingRequest = await this.createNextApiBookingRequest(req, oAuthClientId, undefined, isEmbed);
        const res = await handleCancelBooking({
          bookingData: bookingRequest.body,
          userId: bookingRequest.userId,

View on GitHub (pinned to 176037d0af)