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.
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)
Solutions
- Use booking.uid (string), not booking.id (number), in the cancel path.
- Audit response mapping to surface uid as the canonical identifier.
- 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
- Always key bookings by uid, not id, in client code.
- Add a unit test asserting the cancel path rejects numeric ids before send.
- Label uid vs id clearly in API response mappings.
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
- Can't cancel booking with uid=${bookingUid} because it has b
- Invalid seatUid: this seat does not exist or has already bee
- Invalid seatUid: this seat does not belong to this booking.
- ApiKeysService -Cannot set both apiKeyDaysValid and apiKeyNe
- teamId is required for team events, please provide a valid t
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/e3eedc9ca176173b.
Report an issue: GitHub.