{"record":{"id":"e890e2c5ceb5701c","repo":"calcom/cal.diy","slug":"attendee-with-this-email-can-t-book-because-the-ma-e890e2","errorCode":null,"errorMessage":"Attendee with this email can't book because the maximum number of active bookings has been reached. You can reschedule your existing booking (${errorData.rescheduleUid}) to a new timeslot instead.","messagePattern":"Attendee with this email can't book because the maximum number of active bookings has been reached\\. You can reschedule your existing booking \\((.+?)\\) to a new timeslot instead\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/errors.service.ts","lineNumber":63,"sourceCode":"          `The event type can't be booked at the \"start\" time provided. This could be because it's too soon (violating the minimum booking notice) or too far in the future (outside the event's scheduling window). Try fetching available slots first using the GET /v2/slots endpoint and then make a booking with \"start\" time equal to one of the available slots.`\n        );\n      } else if (error.message === \"Attempting to book a meeting in the past.\") {\n        throw new BadRequestException(\"Attempting to book a meeting in the past.\");\n      } else if (error.message === \"hosts_unavailable_for_booking\") {\n        throw new BadRequestException(hostsUnavaile);\n      } else if (error.message === \"booker_limit_exceeded_error\") {\n        throw new BadRequestException(\n          \"Attendee with this email can't book because the maximum number of active bookings has been reached.\"\n        );\n      } else if (error.message === \"booker_limit_exceeded_error_reschedule\") {\n        const errorData =\n          \"data\" in error ? (error.data as { rescheduleUid: string }) : { rescheduleUid: undefined };\n        let message =\n          \"Attendee with this email can't book because the maximum number of active bookings has been reached.\";\n        if (errorData?.rescheduleUid) {\n          message += ` You can reschedule your existing booking (${errorData.rescheduleUid}) to a new timeslot instead.`;\n        }\n        throw new BadRequestException(message);\n      }\n    }\n    throw error;\n  }\n}\n","sourceCodeStart":45,"sourceCodeEnd":69,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/errors.service.ts#L45-L69","documentation":"Thrown by handleBookingError when error.message === 'booker_limit_exceeded_error_reschedule'. BadRequestException (HTTP 400). Same per-attendee limit as 331, but the engine attached a rescheduleUid on error.data pointing at an existing booking the attendee could reschedule instead. The composed message includes that uid so the client can offer a reschedule flow.","triggerScenarios":"Booking against a bookerLimit event type when the attendee is at the limit, and the booking engine identified an existing booking that could be rescheduled to free capacity. The engine returns booker_limit_exceeded_error_reschedule with data.rescheduleUid.","commonSituations":"Same as 331 plus the engine's reschedule suggestion path — typically when the event type allows rescheduling as an alternative to creating a new booking. The error is meant to be actionable: reschedule the referenced booking instead of retrying the create.","solutions":["Parse rescheduleUid from the error message and call POST /v2/bookings/{rescheduleUid}/reschedule instead of creating a new booking.","If rescheduling is not desired, cancel the referenced booking then retry the create (drops back to the 331 path).","Raise the event type's bookerLimit if appropriate.","Pre-check the attendee's active bookings and proactively offer reschedule before the limit is hit."],"exampleFix":"// before\ntry { await api.post('/v2/bookings', body); }\ncatch (e) { /* surface raw 400 */ }\n\n// after\ntry { await api.post('/v2/bookings', body); }\ncatch (e) {\n  const m = e.message.match(/reschedule your existing booking \\(([^)]+)\\)/);\n  if (m) { await api.post(`/v2/bookings/${m[1]}/reschedule`, { start: body.start }); }\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":"const active = await api.get(`/v2/bookings?attendeeEmail=${encodeURIComponent(email)}&status=upcoming`);\nif (active.data.length >= bookerLimit && active.data[0]?.uid) {\n  // proactively reschedule instead of creating\n  await api.post(`/v2/bookings/${active.data[0].uid}/reschedule`, { start: body.start });\n}","typeGuard":"null","tryCatchPattern":"try { await api.post('/v2/bookings', body); }\ncatch (e) {\n  const m = e.response?.data?.message?.match(/reschedule your existing booking \\(([^)]+)\\)/);\n  if (e.response?.status === 400 && m) {\n    await api.post(`/v2/bookings/${m[1]}/reschedule`, { start: body.start, reschedulingReason: 'limit' });\n  } else throw e;\n}","preventionTips":["Parse rescheduleUid from the error message and reschedule instead of retrying create.","Proactively offer reschedule when the attendee is near the bookerLimit.","Cancel the referenced booking if reschedule is not acceptable."],"tags":["api","bookings","booker-limit","reschedule","nestjs"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}