calcom/cal.diy · error · BadRequestException

Unsupported integration: ${integrationSlug}

Error message

Unsupported integration: ${integrationSlug}

What it means

A 400 BadRequestException thrown by BookingLocationIntegrationService_2024_08_13.handleIntegrationLocationUpdate when the provided integration slug doesn't map to any entry in apiToInternalintegrationsMapping. The mapping defines 29 supported integrations (cal-video, google-meet, zoom, office365-video, whereby-video, etc.). If the client sends an integration value not in this mapping, the lookup returns undefined.

Source

Thrown at apps/api/v2/src/platform/bookings/2024-08-13/services/booking-location-integration.service.ts:81

    private readonly credentialService: BookingLocationCredentialService_2024_08_13
  ) {}

  async handleIntegrationLocationUpdate(
    existingBooking: BookingForLocationUpdate,
    inputLocation: { type: "integration"; integration: Integration_2024_08_13 },
    user: ApiAuthGuardUser,
    existingBookingHost: { organizationId: number | null } | null
  ): Promise<BookingLocationResponse> {
    if (!existingBookingHost) {
      throw new NotFoundException(`No user found for booking with uid=${existingBooking.uid}`);
    }

    const integrationSlug = inputLocation.integration;
    const internalLocation =
      apiToInternalintegrationsMapping[integrationSlug as keyof typeof apiToInternalintegrationsMapping];

    if (!internalLocation) {
      throw new BadRequestException(`Unsupported integration: ${integrationSlug}`);
    }

    const booking = await this.bookingsRepository.getBookingByIdWithUserAndEventDetails(existingBooking.id);
    if (!bookingHasUser(booking)) {
      throw new NotFoundException(`Could not load booking details for uid=${existingBooking.uid}`);
    }

    const ctx: IntegrationHandlerContext = {
      existingBooking,
      booking,
      integrationSlug,
      internalLocation,
      user,
      existingBookingHost,
      inputLocation,
    };

    switch (integrationSlug) {

View on GitHub (pinned to 176037d0af)

Solutions

  1. Check the integration value against the supported list: cal-video, google-meet, zoom, office365-video, whereby-video, whatsapp-video, webex-video, telegram-video, tandem, sylaps-video, skype-video, sirius-video, signal-video, shimmer-video, salesroom-video, roam-video, riverside-video, ping-video, mirotalk-video, jitsi, jelly-video, jelly-conferencing, huddle, facetime-video, element-call-video, eightxeight-video, discord-video, demodesk-video, campfire-video.
  2. Use the exact slug string with correct casing and hyphens — e.g., 'google-meet' not 'Google Meet' or 'google_meet'.
  3. If you believe the integration should be supported, verify both supportedIntegrations and apiToInternalintegrationsMapping include it — a mismatch is a code bug.
  4. For Microsoft Teams specifically, use 'office365-video', not 'ms-teams' or 'teams'.

Example fix

// before — wrong integration slug
PATCH /v2/bookings/abc-123/location
{ "type": "integration", "integration": "ms-teams" }
// -> 400: Unsupported integration: ms-teams

// after — correct slug
PATCH /v2/bookings/abc-123/location
{ "type": "integration", "integration": "office365-video" }
Defensive patterns

Strategy: validation

Validate before calling

// Validate the integration slug against supported values before the API call
const SUPPORTED_INTEGRATIONS = [
  'cal-video', 'google-meet', 'zoom', 'office365-video', 'whereby-video',
  'whatsapp-video', 'webex-video', 'telegram-video', 'tandem', 'sylaps-video',
  'skype-video', 'sirius-video', 'signal-video', 'shimmer-video', 'salesroom-video',
  'roam-video', 'riverside-video', 'ping-video', 'mirotalk-video', 'jitsi',
  'jelly-video', 'jelly-conferencing', 'huddle', 'facetime-video',
  'element-call-video', 'eightxeight-video', 'discord-video', 'demodesk-video', 'campfire-video'
];

function validateIntegration(slug) {
  if (!SUPPORTED_INTEGRATIONS.includes(slug)) {
    throw new Error(`Unsupported integration '${slug}'. Use one of: ${SUPPORTED_INTEGRATIONS.join(', ')}`);
  }
  return slug;
}

validateIntegration(integrationSlug);
await api.updateBookingLocation(bookingUid, { type: 'integration', integration: integrationSlug });

Try / catch

try {
  await api.updateBookingLocation(bookingUid, { type: 'integration', integration: slug });
} catch (err) {
  if (err.statusCode === 400 && err.message.includes('Unsupported integration')) {
    // Fall back to cal-video which is always available
    await api.updateBookingLocation(bookingUid, { type: 'integration', integration: 'cal-video' });
  } else { throw err; }
}

Prevention

When it happens

Trigger: PATCH /v2/bookings/{bookingUid}/location with { type: 'integration', integration: '<slug>' } where <slug> is not one of the 29 supported values. Note that the input DTO validates against supportedIntegrations via @IsIn, so this error is a secondary defense — it fires if validation is bypassed or if the mapping and the supportedIntegrations array fall out of sync.

Common situations: Client sends a typo like 'google_meet' instead of 'google-meet', or 'ms-teams' instead of 'office365-video'. A new integration was added to supportedIntegrations but not to apiToInternalintegrationsMapping (or vice versa). The integration slug casing doesn't match. A custom integration slug was used that isn't registered.

Related errors


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