{"record":{"id":"35bc530dc484799a","repo":"calcom/cal.diy","slug":"missing-attendee-phone-number-it-is-required-by","errorCode":null,"errorMessage":"Missing attendee phone number - it is required by the event type. Pass it as \"attendee.phoneNumber\" string in the request.","messagePattern":"Missing attendee phone number - it is required by the event type\\. Pass it as \"attendee\\.phoneNumber\" string in the request\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":247,"sourceCode":"    const eventTypeBookingFields = eventTypeBookingFieldsSchema\n      .parse(eventType.bookingFields)\n      .filter((field) => !field.editable.startsWith(\"system\") || field.name === \"smsReminderNumber\");\n\n    if (!eventTypeBookingFields.length) {\n      return true;\n    }\n\n    for (const eventTypeBookingField of eventTypeBookingFields) {\n      if (\n        eventTypeBookingField.required &&\n        (bookingFieldsResponses[eventTypeBookingField.name] === null ||\n          bookingFieldsResponses[eventTypeBookingField.name] === undefined)\n      ) {\n        if (\n          eventTypeBookingField.name === \"attendeePhoneNumber\" ||\n          eventTypeBookingField.name === \"smsReminderNumber\"\n        ) {\n          throw new BadRequestException(\n            `Missing attendee phone number - it is required by the event type. Pass it as \"attendee.phoneNumber\" string in the request.`\n          );\n        }\n        throw new BadRequestException(\n          `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.`\n        );\n      }\n\n      const bookingFieldResponseValue = bookingFieldsResponses[eventTypeBookingField.name];\n      if (bookingFieldResponseValue !== undefined) {\n        const bookingFieldResponseValueType = typeof bookingFieldResponseValue;\n        let expectedBookingFieldResponseValueType = \"\";\n        let isValidType = false;\n        const eventTypeBookingFieldType = eventTypeBookingField.type;\n\n        switch (eventTypeBookingFieldType) {\n          case \"phone\":\n            expectedBookingFieldResponseValueType = \"string\";","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L229-L265","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add attendee.phoneNumber as a string in the request body's attendees array (e.g. attendees: [{ name, email, phoneNumber: '+1234567890' }]).","Fetch the event type (GET /v2/event-types/:id) and inspect bookingFields to see which are required before building the request.","If phone should be optional, update the event type booking field to required: false in Cal.com event settings."],"exampleFix":"// before\nconst body = { attendees: [{ name: 'Jane', email: 'jane@example.com' }] };\n// after\nconst body = { attendees: [{ name: 'Jane', email: 'jane@example.com', phoneNumber: '+18005551234' }] };","handlingStrategy":"validation","validationCode":"const et = await client.get(`/v2/event-types/${eventTypeId}`);\nconst needsPhone = et.bookingFields?.some(f => f.required && ['attendeePhoneNumber','smsReminderNumber'].includes(f.name));\nif (needsPhone) for (const a of body.attendees) if (!a.phoneNumber) throw new Error('phoneNumber required');","typeGuard":"function attendeeHasPhone(a: { phoneNumber?: string }): a is { phoneNumber: string } {\n  return typeof a.phoneNumber === 'string' && a.phoneNumber.length > 0;\n}","tryCatchPattern":"try { await client.post('/v2/bookings', body); }\ncatch (e) {\n  if (e.status === 400 && /attendee phone number/i.test(e.message)) { /* prompt user for phone, retry */ }\n  else throw e;\n}","preventionTips":["Inspect event type bookingFields before building the form","Require phone input in the UI when the event type demands it","Keep a mapping of event types to their required fields"],"tags":["api-v2","bookings","validation","required-field","phone"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}