{"record":{"id":"869621fb3bdd510f","repo":"calcom/cal.diy","slug":"invalid-type-for-booking-field-eventtypebooking","errorCode":null,"errorMessage":"Invalid type for booking field '${eventTypeBookingField.name}'. Expected type ${expectedBookingFieldResponseValueType} (compatible with field type '${eventTypeBookingFieldType}'), but received ${bookingFieldResponseValueType}.","messagePattern":"Invalid type for booking field '(.+?)'\\. Expected type (.+?) \\(compatible with field type '(.+?)'\\), but received (.+?)\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":365,"sourceCode":"                  `Invalid option '${submittedValue}' for booking field '${\n                    eventTypeBookingField.name\n                  }'. Allowed options are: ${allowedOptionValues.join(\", \")}.`\n                );\n              }\n            }\n            break;\n          case \"url\":\n            expectedBookingFieldResponseValueType = \"string\";\n            isValidType = bookingFieldResponseValueType === \"string\";\n            break;\n          default:\n            // note(Lauris): by default pass the field if we have a missing \"case\" in the switch\n            isValidType = true;\n            break;\n        }\n\n        if (!isValidType) {\n          throw new BadRequestException(\n            `Invalid type for booking field '${eventTypeBookingField.name}'. Expected type ${expectedBookingFieldResponseValueType} (compatible with field type '${eventTypeBookingFieldType}'), but received ${bookingFieldResponseValueType}.`\n          );\n        }\n      }\n    }\n\n    return true;\n  }\n\n  private isValidSingleOptionValue(\n    bookingFieldResponseValue: string | number,\n    eventTypeBookingFieldOptions: string[]\n  ): boolean {\n    if (eventTypeBookingFieldOptions.length === 0) {\n      // note(Lauris): If no options defined, cannot validate against them, so pass.\n      return true;\n    }\n    return eventTypeBookingFieldOptions.some((val) => val === String(bookingFieldResponseValue));","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L347-L383","documentation":"Thrown at the end of the per-field validation switch as a fallback when isValidType is false for any booking field whose type was handled (string, number, boolean, select, multiselect, checkbox, radio, url). The message reports the expected JS type, the field's declared type, and the received type. BadRequestException (HTTP 400).","triggerScenarios":"A booking field response has a runtime type that does not match the expected type for the field — e.g. sending a string for a boolean field, a number for an array field, or an object for a string field.","commonSituations":"Loosely-typed JSON payloads from integrations; sending 'true' (string) instead of true (boolean) for boolean fields; sending a single value instead of an array for multiselect/checkbox; form serialization converting types.","solutions":["Coerce the value to the expected JS type before submitting (boolean -> true/false, array for multiselect/checkbox).","Re-fetch the event type to confirm each field's type and align payload accordingly.","Add a serialization layer that respects JSON types rather than form-encoded strings."],"exampleFix":"// before — boolean field sent as string\nconst responses = { optIn: 'true' };\n// after\nconst responses = { optIn: true };","handlingStrategy":"type-guard","validationCode":"function coerceForType(value: unknown, type: string) {\n  switch (type) {\n    case 'boolean': return typeof value === 'boolean' ? value : Boolean(value);\n    case 'number': return typeof value === 'number' ? value : Number(value);\n    case 'multiselect': case 'checkbox': return Array.isArray(value) ? value : [value];\n    default: return typeof value === 'string' ? value : String(value);\n  }\n}","typeGuard":"function matchesExpected(value: unknown, type: string): boolean {\n  switch (type) {\n    case 'boolean': return typeof value === 'boolean';\n    case 'number': return typeof value === 'number';\n    case 'select': case 'radio': return typeof value === 'string' || typeof value === 'number';\n    case 'multiselect': case 'checkbox': return Array.isArray(value);\n    case 'url': return typeof value === 'string';\n    default: return true;\n  }\n}","tryCatchPattern":"try { await client.post('/v2/bookings', body); }\ncatch (e) {\n  if (e.status === 400 && /Invalid type for booking field/.test(e.message)) { /* coerce value, retry */ }\n  else throw e;\n}","preventionTips":["Send JSON with native types (not form-encoded strings)","Coerce form values to proper types before submission","Map field type to expected JS type in a shared util"],"tags":["api-v2","bookings","validation","type-mismatch"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}