calcom/cal.diy · error · BadRequestException

Attendee with this email can't book because the maximum numb

Error message

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.

What it means

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.

Source

Thrown at apps/api/v2/src/platform/bookings/2024-08-13/services/errors.service.ts:63

          `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.`
        );
      } else if (error.message === "Attempting to book a meeting in the past.") {
        throw new BadRequestException("Attempting to book a meeting in the past.");
      } else if (error.message === "hosts_unavailable_for_booking") {
        throw new BadRequestException(hostsUnavaile);
      } else if (error.message === "booker_limit_exceeded_error") {
        throw new BadRequestException(
          "Attendee with this email can't book because the maximum number of active bookings has been reached."
        );
      } else if (error.message === "booker_limit_exceeded_error_reschedule") {
        const errorData =
          "data" in error ? (error.data as { rescheduleUid: string }) : { rescheduleUid: undefined };
        let message =
          "Attendee with this email can't book because the maximum number of active bookings has been reached.";
        if (errorData?.rescheduleUid) {
          message += ` You can reschedule your existing booking (${errorData.rescheduleUid}) to a new timeslot instead.`;
        }
        throw new BadRequestException(message);
      }
    }
    throw error;
  }
}

View on GitHub (pinned to 176037d0af)

Solutions

  1. Parse rescheduleUid from the error message and call POST /v2/bookings/{rescheduleUid}/reschedule instead of creating a new booking.
  2. If rescheduling is not desired, cancel the referenced booking then retry the create (drops back to the 331 path).
  3. Raise the event type's bookerLimit if appropriate.
  4. Pre-check the attendee's active bookings and proactively offer reschedule before the limit is hit.

Example fix

// before
try { await api.post('/v2/bookings', body); }
catch (e) { /* surface raw 400 */ }

// after
try { await api.post('/v2/bookings', body); }
catch (e) {
  const m = e.message.match(/reschedule your existing booking \(([^)]+)\)/);
  if (m) { await api.post(`/v2/bookings/${m[1]}/reschedule`, { start: body.start }); }
  else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const active = await api.get(`/v2/bookings?attendeeEmail=${encodeURIComponent(email)}&status=upcoming`);
if (active.data.length >= bookerLimit && active.data[0]?.uid) {
  // proactively reschedule instead of creating
  await api.post(`/v2/bookings/${active.data[0].uid}/reschedule`, { start: body.start });
}

Type guard

null

Try / catch

try { await api.post('/v2/bookings', body); }
catch (e) {
  const m = e.response?.data?.message?.match(/reschedule your existing booking \(([^)]+)\)/);
  if (e.response?.status === 400 && m) {
    await api.post(`/v2/bookings/${m[1]}/reschedule`, { start: body.start, reschedulingReason: 'limit' });
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/e890e2c5ceb5701c. Report an issue: GitHub.