calcom/cal.diy · warning · BadRequestException

Invalid conferencing app. Available apps: GOOGLE_MEET.

Error message

Invalid conferencing app. Available apps: GOOGLE_MEET.

What it means

Thrown by ConferencingService.connectUserNonOauthApp when the app slug is not GOOGLE_MEET. This branch handles apps that do not require OAuth (only Google Meet, which derives from the user's existing Google Calendar connection). Returns HTTP 400. The endpoint POST /v2/conferencing/{app}/connect only documents GOOGLE_MEET as a valid value.

Source

Thrown at apps/api/v2/src/modules/conferencing/services/conferencing.service.ts:51

    private readonly conferencingRepository: ConferencingRepository,
    private readonly usersRepository: UsersRepository,
    private readonly tokensRepository: TokensRepository,
    private readonly googleMeetService: GoogleMeetService,
    private readonly zoomVideoService: ZoomVideoService,
    private readonly office365VideoService: Office365VideoService
  ) {}

  async getConferencingApps(userId: number) {
    return this.conferencingRepository.findConferencingApps(userId);
  }

  async connectUserNonOauthApp(app: string, userId: number) {
    switch (app) {
      case GOOGLE_MEET:
        const credential = await this.googleMeetService.connectGoogleMeetToUser(userId);
        return credential;
      default:
        throw new BadRequestException("Invalid conferencing app. Available apps: GOOGLE_MEET.");
    }
  }

  async connectOauthApps(
    app: string,
    code: string,
    decodedCallbackState: OAuthCallbackState,
    teamId?: number
  ) {
    const userId = await this.tokensRepository.getAccessTokenOwnerId(decodedCallbackState.accessToken);
    if (!userId) {
      throw new UnauthorizedException("Invalid Access token.");
    }
    switch (app) {
      case ZOOM:
        return await this.zoomVideoService.connectZoomApp(decodedCallbackState, code, userId, teamId);

      case OFFICE_365_VIDEO:

View on GitHub (pinned to 176037d0af)

Solutions

  1. For GOOGLE_MEET only, call POST /v2/conferencing/google_meet/connect.
  2. For ZOOM and OFFICE_365_VIDEO, use the OAuth flow: GET /v2/conferencing/{app}/oauth/auth-url, redirect, then handle the callback.
  3. Validate the app slug client-side against the documented set for the connect endpoint before issuing the request.
  4. Update the API client to expose separate connect/connectOauth methods keyed on the app's OAuth requirement.

Example fix

// before
await api.connectConferencing('zoom'); // wrong endpoint

// after
const OAUTH_APPS = ['zoom', 'office365_video'];
if (OAUTH_APPS.includes(app)) {
  const { data } = await api.getOauthUrl(app);
  window.location.href = data.authUrl;
} else {
  await api.connectConferencing(app); // google_meet
}
Defensive patterns

Strategy: validation

Validate before calling

import { GOOGLE_MEET } from '@calcom/platform-constants';

function validateNonOauthApp(app: string): void {
  if (app !== GOOGLE_MEET) {
    throw new Error(`${app} cannot be connected directly. Use the OAuth flow for ${app}.`);
  }
}

validateNonOauthApp(req.params.app);

Type guard

import { GOOGLE_MEET } from '@calcom/platform-constants';

function isDirectConnectApp(app: string): app is typeof GOOGLE_MEET {
  return app === GOOGLE_MEET;
}

Try / catch

try {
  await conferencingService.connectUserNonOauthApp(app, userId);
} catch (e) {
  if (e instanceof BadRequestException && /Invalid conferencing app/.test(e.message)) {
    return res.status(400).json({ code: 'use_oauth_flow', supported: [GOOGLE_MEET] });
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling POST /v2/conferencing/{app}/connect with app=zoom or app=office365_video — those require the OAuth flow (auth-url → callback), not the direct connect endpoint. Also any unknown slug like 'teams'.

Common situations: Client routes all conferencing connects through the same endpoint regardless of OAuth requirement; hardcoded slug list out of sync with the constants; integration assumes all apps connect directly.

Related errors


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