calcom/cal.diy · error · BadRequestException

Missing attendee phone number - it is required by the event

Error message

Missing attendee phone number - it is required by the event type. Pass it as "attendee.phoneNumber" string in the request.

What it means

Thrown during booking creation when the event type declares attendeePhoneNumber or smsReminderNumber as a required booking field, but the request's bookingFieldsResponses does not include a non-null value for it. The service iterates all required eventTypeBookingFields and, for these two phone-related fields specifically, emits a tailored message instructing the caller to pass attendee.phoneNumber.

Source

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

    const eventTypeBookingFields = eventTypeBookingFieldsSchema
      .parse(eventType.bookingFields)
      .filter((field) => !field.editable.startsWith("system") || field.name === "smsReminderNumber");

    if (!eventTypeBookingFields.length) {
      return true;
    }

    for (const eventTypeBookingField of eventTypeBookingFields) {
      if (
        eventTypeBookingField.required &&
        (bookingFieldsResponses[eventTypeBookingField.name] === null ||
          bookingFieldsResponses[eventTypeBookingField.name] === undefined)
      ) {
        if (
          eventTypeBookingField.name === "attendeePhoneNumber" ||
          eventTypeBookingField.name === "smsReminderNumber"
        ) {
          throw new BadRequestException(
            `Missing attendee phone number - it is required by the event type. Pass it as "attendee.phoneNumber" string in the request.`
          );
        }
        throw new BadRequestException(
          `Missing required booking field response: ${eventTypeBookingField.name} - it is required by the event type booking fields, but missing in the bookingFieldsResponses. You can fetch the event type with ID ${eventType.id} to see the required fields.`
        );
      }

      const bookingFieldResponseValue = bookingFieldsResponses[eventTypeBookingField.name];
      if (bookingFieldResponseValue !== undefined) {
        const bookingFieldResponseValueType = typeof bookingFieldResponseValue;
        let expectedBookingFieldResponseValueType = "";
        let isValidType = false;
        const eventTypeBookingFieldType = eventTypeBookingField.type;

        switch (eventTypeBookingFieldType) {
          case "phone":
            expectedBookingFieldResponseValueType = "string";

View on GitHub (pinned to 176037d0af)

Solutions

  1. Add attendee.phoneNumber as a string in the request body's attendees array (e.g. attendees: [{ name, email, phoneNumber: '+1234567890' }]).
  2. Fetch the event type (GET /v2/event-types/:id) and inspect bookingFields to see which are required before building the request.
  3. If phone should be optional, update the event type booking field to required: false in Cal.com event settings.

Example fix

// before
const body = { attendees: [{ name: 'Jane', email: 'jane@example.com' }] };
// after
const body = { attendees: [{ name: 'Jane', email: 'jane@example.com', phoneNumber: '+18005551234' }] };
Defensive patterns

Strategy: validation

Validate before calling

const et = await client.get(`/v2/event-types/${eventTypeId}`);
const needsPhone = et.bookingFields?.some(f => f.required && ['attendeePhoneNumber','smsReminderNumber'].includes(f.name));
if (needsPhone) for (const a of body.attendees) if (!a.phoneNumber) throw new Error('phoneNumber required');

Type guard

function attendeeHasPhone(a: { phoneNumber?: string }): a is { phoneNumber: string } {
  return typeof a.phoneNumber === 'string' && a.phoneNumber.length > 0;
}

Try / catch

try { await client.post('/v2/bookings', body); }
catch (e) {
  if (e.status === 400 && /attendee phone number/i.test(e.message)) { /* prompt user for phone, retry */ }
  else throw e;
}

Prevention

When it happens

Trigger: Creating a booking for an event type that has SMS reminders or phone collection enabled (required), without providing attendee.phoneNumber in the request payload. The field name maps internally to attendeePhoneNumber but the API input uses attendee.phoneNumber.

Common situations: Event type configured with 'Request phone number' or SMS workflow enabled and required; integration built against an event type whose settings changed to require phone; frontend form omitting the phone field.

Related errors


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