{"record":{"id":"0778bcfa7b4f27a2","repo":"calcom/cal.diy","slug":"reassigned-booking-with-uid-bookinguid-was-not","errorCode":null,"errorMessage":"Reassigned booking with uid=${bookingUid} was not found in the database","messagePattern":"Reassigned booking with uid=(.+?) was not found in the database","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":1045,"sourceCode":"        platformClientParams,\n        reassignedById: reassignedByUser.id,\n        actionSource: \"API_V2\",\n        reassignedByUuid: reassignedByUser.uuid,\n      });\n    } catch (error) {\n      if (error instanceof Error) {\n        if (error.message === \"no_available_users_found_error\") {\n          throw new BadRequestException(\n            \"Can't reassign the booking because no other host is available at that time.\"\n          );\n        }\n      }\n      throw error;\n    }\n\n    const reassigned = await this.bookingsRepository.getByUidWithUser(bookingUid);\n    if (!reassigned) {\n      throw new NotFoundException(`Reassigned booking with uid=${bookingUid} was not found in the database`);\n    }\n\n    return this.outputService.getOutputReassignedBooking(reassigned);\n  }\n\n  async reassignBookingToUser(\n    bookingUid: string,\n    newUserId: number,\n    reassignedByUser: ApiAuthGuardUser,\n    body: ReassignToUserBookingInput_2024_08_13\n  ) {\n    const booking = await this.bookingsRepository.getByUidWithEventType(bookingUid);\n    if (!booking) {\n      throw new NotFoundException(`Booking with uid=${bookingUid} was not found in the database`);\n    }\n    if (!booking.eventType) {\n      throw new BadRequestException(\n        `Event type with id=${booking.eventTypeId} was not found in the database`","sourceCodeStart":1027,"sourceCodeEnd":1063,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L1027-L1063","documentation":"Thrown near the end of reassignBooking after roundRobinReassignment succeeds but the follow-up getByUidWithUser(bookingUid) returns null. It is a NestJS NotFoundException (HTTP 404) indicating the booking vanished between mutation and re-fetch. This signals a data-integrity or concurrency problem rather than normal usage.","triggerScenarios":"The booking being deleted (hard delete or cascade) by another process in the window between the reassignment commit and the re-fetch; a transaction rollback that left the reassignment partially applied; a uid casing/mismatch bug in the repository query.","commonSituations":"Concurrent cleanup jobs that purge old/cancelled bookings; manual DB intervention during testing; replication lag where the read goes to a stale replica; extremely rare race conditions under load.","solutions":["Retry the GET /v2/bookings/{uid} after a short delay to rule out transient read lag.","Confirm the booking still exists in the database (it may have been deleted concurrently).","Check for background jobs or cascades that delete bookings around reassignment.","If reproducible, escalate to backend/DBA to inspect the reassignment transaction boundaries."],"exampleFix":"// before\nconst result = await apiClient.post(`/v2/bookings/${uid}/reassign`);\n\n// after\nconst reassigned = await withRetry(\n  () => apiClient.get(`/v2/bookings/${uid}`).then(r => r.data),\n  { retries: 3, delayMs: 200 }\n);\nif (!reassigned) throw new Error(`Booking ${uid} disappeared after reassign - possible concurrent delete`);","handlingStrategy":"retry","validationCode":"// Pre-flight existence check (does not prevent the race but cheap to do)\nconst exists = await apiClient.get(`/v2/bookings/${uid}`).then(() => true).catch(e => e.response?.status !== 404);\nif (!exists) throw new Error(`Booking ${uid} missing before reassign`);","typeGuard":"function isPostReassignMissing(err: unknown): boolean {\n  return typeof err === 'object' && err !== null &&\n    (err as any).response?.status === 404 &&\n    /Reassigned booking.*not found/i.test((err as any).response?.data?.message ?? '');\n}","tryCatchPattern":"try {\n  await apiClient.post(`/v2/bookings/${uid}/reassign`);\n} catch (err) {\n  if (isPostReassignMissing(err)) {\n    // transient read failure or concurrent delete - re-read with backoff\n    await withRetry(() => apiClient.get(`/v2/bookings/${uid}`), { retries: 3, delayMs: 250 });\n    return;\n  }\n  throw err;\n}","preventionTips":["Avoid running destructive cleanup jobs concurrently with reassignment.","Read from the primary (not a lagging replica) for post-mutation verification.","Re-read with a short retry before reporting failure to the user."],"tags":["data-integrity","race-condition","booking","api-v2","reassign","not-found"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}