{"record":{"id":"96bc2ccac9e84e6d","repo":"calcom/cal.diy","slug":"missing-or-invalid-location-value-for-type-inpu","errorCode":null,"errorMessage":"Missing or invalid location value for type: ${inputLocation.type}","messagePattern":"Missing or invalid location value for type: (.+?)","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/booking-location.service.ts","lineNumber":116,"sourceCode":"\n    const existingBookingHost = await this.usersRepository.findById(existingBooking.userId);\n\n    if (!existingBookingHost) {\n      throw new NotFoundException(`No user found for booking with uid=${bookingUid}`);\n    }\n\n    if (inputLocation.type === \"integration\") {\n      return this.integrationService.handleIntegrationLocationUpdate(\n        existingBooking,\n        inputLocation,\n        user,\n        existingBookingHost\n      );\n    }\n\n    const bookingLocation = this.getNonIntegrationLocationValue(inputLocation);\n    if (!bookingLocation) {\n      throw new BadRequestException(`Missing or invalid location value for type: ${inputLocation.type}`);\n    }\n\n    const bookingFieldsLocation = this.inputService.transformLocation(inputLocation);\n\n    const responses = (existingBooking.responses || {}) as Record<string, unknown>;\n    const { location: _existingLocation, ...rest } = responses;\n\n    const updatedBookingResponses = {\n      ...rest,\n      location: bookingFieldsLocation,\n    };\n\n    const metadataWithoutVideoUrl = this.getMetadataWithoutVideoCallUrl(existingBooking.metadata);\n\n    await this.bookingVideoService.deleteOldVideoMeetingIfNeeded(existingBooking.id);\n\n    const updatedBooking = await this.bookingsRepository.updateBooking(bookingUid, {\n      location: bookingLocation,","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/booking-location.service.ts#L98-L134","documentation":"Thrown in updateLocation for the non-integration branch when getNonIntegrationLocationValue returns undefined. That helper returns the value field for each known type (address, link, phone, attendeeAddress, attendeePhone, attendeeDefined); it returns undefined when the type is unrecognized OR when the corresponding value field is empty/undefined.","triggerScenarios":"PATCH booking location with location.type other than \"integration\", but the matching payload field is missing or empty — e.g. { type: \"phone\" } with no phone, { type: \"link\" } with empty link, { type: \"address\" } with no address.","commonSituations":"Client omits the value field for the chosen location type; sends a blank string; uses a location type not in the supported set; frontend bug building the payload.","solutions":["Provide the required value field for the chosen location type (phone for \"phone\"/\"attendeePhone\", link for \"link\", address for \"address\"/\"attendeeAddress\", location for \"attendeeDefined\").","Use one of the supported location types (address, link, phone, attendeeAddress, attendeePhone, attendeeDefined, integration).","Validate the payload on the client before sending."],"exampleFix":"// before\n{ location: { type: 'phone' } }            // missing phone -> BadRequestException\n// after\n{ location: { type: 'phone', phone: '+15551234567' } }","handlingStrategy":"type-guard","validationCode":"// Build and validate the location payload before sending.\nfunction buildLocation(loc) {\n  if (loc.type === 'phone' && !loc.phone) throw new Error('phone location requires a phone value');\n  if (loc.type === 'link' && !loc.link) throw new Error('link location requires a link value');\n  if (loc.type === 'address' && !loc.address) throw new Error('address location requires an address value');\n  if (loc.type === 'attendeeDefined' && !loc.location) throw new Error('attendeeDefined requires a location value');\n  return loc;\n}","typeGuard":"function isValidLocationPayload(loc: { type: string; [k: string]: unknown }): boolean {\n  switch (loc.type) {\n    case 'address': return typeof loc.address === 'string' && loc.address.length > 0;\n    case 'link': return typeof loc.link === 'string' && loc.link.length > 0;\n    case 'phone': return typeof loc.phone === 'string' && loc.phone.length > 0;\n    case 'attendeeAddress': return typeof loc.address === 'string' && loc.address.length > 0;\n    case 'attendeePhone': return typeof loc.phone === 'string' && loc.phone.length > 0;\n    case 'attendeeDefined': return typeof loc.location === 'string' && loc.location.length > 0;\n    case 'integration': return true;\n    default: return false;\n  }\n}","tryCatchPattern":"try {\n  await api.patch(`/v2/bookings/${uid}/location`, { location: buildLocation(payload) });\n} catch (err) {\n  if (err.status === 400 && /Missing or invalid location value/.test(err.message)) {\n    // fix the payload: add the missing value field for the chosen type\n  }\n  throw err;\n}","preventionTips":["Always include the value field matching the location type when building the payload.","Use a builder/validator function on the client to construct location objects.","Reference apiToInternalintegrationsMapping and the supported non-integration types."],"tags":["validation","location","bad-request"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}