{"record":{"id":"d643c9c8a33fc4c6","repo":"calcom/cal.diy","slug":"missing-required-booking-field-response-eventty","errorCode":null,"errorMessage":"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.","messagePattern":"Missing required booking field response: (.+?) - it is required by the event type booking fields, but missing in the bookingFieldsResponses\\. You can fetch the event type with ID (.+?) to see the required fields\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":251,"sourceCode":"    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\";\n            isValidType = bookingFieldResponseValueType === \"string\";\n            break;\n          case \"address\":\n            expectedBookingFieldResponseValueType = \"string\";","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L233-L269","documentation":"Thrown during booking creation when any required event type booking field (other than the two phone-specific fields) has a null or undefined value in bookingFieldsResponses. The message names the missing field and references the event type ID so the caller can re-fetch the schema. Maps to HTTP 400 BadRequestException.","triggerScenarios":"A POST /v2/bookings request omits a value for a field the event type marks required (e.g. name, email, a custom question). The loop checks eventTypeBookingField.required && (response === null || response === undefined).","commonSituations":"Custom booking questions added to an event type after the integration was built; standard fields like 'name' or 'email' omitted from the payload; sending an empty string instead of a value (empty string passes because the check is only null/undefined).","solutions":["GET /v2/event-types/:id and review bookingFields — include a non-null value for every field where required is true.","Ensure bookingFieldsResponses includes the field by its exact name (case-sensitive).","If the field should not be required, update the event type configuration in Cal.com."],"exampleFix":"// before — 'title' field is required but omitted\nconst body = { start: '2025-01-01T10:00:00Z', eventTypeId: 123, responses: {} };\n// after\nconst body = { start: '2025-01-01T10:00:00Z', eventTypeId: 123, responses: { title: 'Consultation' } };","handlingStrategy":"validation","validationCode":"const et = await client.get(`/v2/event-types/${eventTypeId}`);\nconst required = et.bookingFields.filter(f => f.required).map(f => f.name);\nconst missing = required.filter(n => body.responses[n] == null);\nif (missing.length) throw new Error(`Missing: ${missing.join(', ')}`);","typeGuard":"function hasAllRequired(responses: Record<string, unknown>, required: string[]): boolean {\n  return required.every(n => responses[n] !== null && responses[n] !== undefined);\n}","tryCatchPattern":"try { await client.post('/v2/bookings', body); }\ncatch (e) {\n  if (e.status === 400 && /Missing required booking field/.test(e.message)) { /* parse field name, collect, retry */ }\n  else throw e;\n}","preventionTips":["Sync event type schemas client-side on load","Build forms dynamically from bookingFields","Treat empty string as invalid for required fields in your own validation"],"tags":["api-v2","bookings","validation","required-field"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}