{"record":{"id":"adc24569f524392c","repo":"calcom/cal.diy","slug":"can-t-reschedule-booking-with-uid-bookinguid-be-adc245","errorCode":null,"errorMessage":"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.","messagePattern":"Can't reschedule booking with uid=(.+?) because it has been cancelled and rescheduled already to booking with uid=(.+?)\\. You probably want to reschedule (.+?) instead by passing it within the request URL\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":836,"sourceCode":"      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);\n\n    if (!booking) {\n      throw new NotFoundException(`Booking with uid=${bookingUid} was not found in the database`);\n    }\n\n    const hasSeatsPresent = booking.seatsReferences.length > 0;","sourceCodeStart":818,"sourceCodeEnd":854,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L818-L854","documentation":"Thrown by canRescheduleBooking when the booking is CANCELLED and the rescheduled flag is true — it was already rescheduled into a new booking. The service looks up the new booking via getByFromReschedule and returns its uid in the message so the caller can redirect. BadRequestException (HTTP 400).","triggerScenarios":"Rescheduling a booking that was previously cancelled because it was rescheduled; the original uid is now superseded by the rescheduledTo uid.","commonSituations":"Client cached the old uid after a reschedule already occurred; webhook-driven retry hitting the superseded booking.","solutions":["Parse the rescheduledTo uid from the error message and re-issue the reschedule against that uid.","Store the latest booking uid locally, updating it whenever a reschedule succeeds.","Consume booking.updated/rescheduled webhooks to keep the active uid current."],"exampleFix":"// before\nawait client.post(`/v2/bookings/${oldUid}/reschedule`, body);\n// after\ntry { await client.post(`/v2/bookings/${oldUid}/reschedule`, body); }\ncatch (e) {\n  const m = e.message.match(/reschedule ([a-z0-9]+)/i);\n  if (m) await client.post(`/v2/bookings/${m[1]}/reschedule`, body);\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":"const b = await client.get(`/v2/bookings/${uid}`);\nif (b.status === 'CANCELLED' && b.rescheduled) throw new Error(`Already rescheduled; use ${b.rescheduledToUid}`);","typeGuard":"function needsRedirect(b: { status: string; rescheduled?: boolean }): boolean {\n  return b.status === 'CANCELLED' && !!b.rescheduled;\n}","tryCatchPattern":"try { await client.post(`/v2/bookings/${uid}/reschedule`, body); }\ncatch (e) {\n  if (e.status === 400) {\n    const m = e.message.match(/reschedule ([a-z0-9]+)/i);\n    if (m) { return client.post(`/v2/bookings/${m[1]}/reschedule`, body); }\n  }\n  throw e;\n}","preventionTips":["Track the latest booking uid locally after each reschedule","Consume reschedule webhooks to update stored uids","Parse redirect uids from error messages as a recovery path"],"tags":["api-v2","bookings","reschedule","cancelled","redirect"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}