{"record":{"id":"7f2f4e17dc25f114","repo":"calcom/cal.diy","slug":"can-t-reschedule-booking-with-uid-bookinguid-be","errorCode":null,"errorMessage":"Can't reschedule booking with uid=${bookingUid} because it has been cancelled. Please provide uid of a booking that is not cancelled.","messagePattern":"Can't reschedule booking with uid=(.+?) because it has been cancelled\\. Please provide uid of a booking that is not cancelled\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":830,"sourceCode":"          booking.seatReferenceUid || \"\",\n          userIsEventTypeAdminOrOwner\n        );\n        return Object.assign(outputBooking, { isPlatformManagedUserBooking });\n      }\n      const outputBooking = await this.outputService.getOutputBooking(databaseBooking);\n      return Object.assign(outputBooking, { isPlatformManagedUserBooking });\n    } catch (error) {\n      this.errorsBookingsService.handleBookingError(error, false);\n    }\n  }\n\n  async canRescheduleBooking(bookingUid: string) {\n    const booking = await this.bookingsRepository.getByUid(bookingUid);\n    if (!booking) {\n      throw new Error(`Booking with uid=${bookingUid} was not found in the database`);\n    }\n    if (booking.status === \"CANCELLED\" && !booking.rescheduled) {\n      throw new BadRequestException(\n        `Can't reschedule booking with uid=${bookingUid} because it has been cancelled. Please provide uid of a booking that is not cancelled.`\n      );\n    }\n    if (booking.status === \"CANCELLED\" && booking.rescheduled) {\n      const rescheduledTo = await this.bookingsRepository.getByFromReschedule(bookingUid);\n      throw new BadRequestException(\n        `Can't reschedule booking with uid=${bookingUid} because it has been cancelled and rescheduled already to booking with uid=${rescheduledTo?.uid}. You probably want to reschedule ${rescheduledTo?.uid} instead by passing it within the request URL.`\n      );\n    }\n    return booking;\n  }\n\n  async shouldRescheduleIndividualSeat(\n    bookingUid: string,\n    isIndividualSeatReschedule: boolean,\n    authUser: AuthOptionalUser\n  ) {\n    const booking = await this.bookingsRepository.getByUidWithUserIdAndSeatsReferencesCount(bookingUid);","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L812-L848","documentation":"Thrown by canRescheduleBooking when the booking exists but its status is CANCELLED and the rescheduled flag is false. This is a hard block: a cancelled booking cannot be rescheduled. BadRequestException (HTTP 400).","triggerScenarios":"A reschedule request (POST /v2/bookings/:uid/reschedule or similar) targeting a booking whose status is CANCELLED and that has not already been rescheduled.","commonSituations":"User cancels then attempts to reschedule instead of rebooking; stale uid held in client state after a cancellation workflow.","solutions":["Create a new booking instead of rescheduling a cancelled one.","Check booking.status === 'CANCELLED' before attempting reschedule and branch to rebook flow.","Re-fetch the booking to confirm its current status before calling reschedule."],"exampleFix":"// before\nawait client.post(`/v2/bookings/${uid}/reschedule`, body);\n// after\nconst b = await client.get(`/v2/bookings/${uid}`);\nif (b.status === 'CANCELLED') {\n  await client.post('/v2/bookings', newBookingBody);\n} else {\n  await client.post(`/v2/bookings/${uid}/reschedule`, body);\n}","handlingStrategy":"validation","validationCode":"const b = await client.get(`/v2/bookings/${uid}`);\nif (b.status === 'CANCELLED') throw new Error('Cannot reschedule a cancelled booking; create a new one');","typeGuard":"function isReschedulable(b: { status: string }): boolean {\n  return b.status !== 'CANCELLED';\n}","tryCatchPattern":"try { await client.post(`/v2/bookings/${uid}/reschedule`, body); }\ncatch (e) {\n  if (e.status === 400 && /has been cancelled/.test(e.message) && !/rescheduled already/.test(e.message)) { /* route to new-booking flow */ }\n  else throw e;\n}","preventionTips":["Check booking status before reschedule","Branch to rebook when status is CANCELLED","Keep client state in sync with cancellation webhooks"],"tags":["api-v2","bookings","reschedule","cancelled","validation"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}