calcom/cal.diy · warning · BadRequestException

Invalid conferencing app, available apps are:

Error message

Invalid conferencing app, available apps are: 

What it means

Thrown by ConferencingService.connectOauthApps when the app slug in the OAuth callback is neither ZOOM nor OFFICE_365_VIDEO — the two apps that support OAuth connect via this path. Returns HTTP 400. Note the message string ends with a trailing space and the actual app list is passed as the second BadRequestException argument (NestJS error cause), so a bare toString() of the error will show only the leading text.

Source

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

  ) {
    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:
        return await this.office365VideoService.connectOffice365App(
          decodedCallbackState,
          code,
          userId,
          teamId
        );

      default:
        throw new BadRequestException(
          "Invalid conferencing app, available apps are: ",
          [ZOOM, OFFICE_365_VIDEO].join(", ")
        );
    }
  }

  async getUserDefaultConferencingApp(userId: number) {
    const user = await this.usersRepository.findById(userId);
    return userMetadata.parse(user?.metadata)?.defaultConferencingApp;
  }

  async checkAppIsValidAndConnected(user: UserWithProfile, appSlug: string) {
    if (!CONFERENCING_APPS.includes(appSlug)) {
      throw new BadRequestException("Invalid app, available apps are: ", CONFERENCING_APPS.join(", "));
    }
    const credentials = await getUsersCredentialsIncludeServiceAccountKey(user);

    const foundApp = getApps(credentials, true).filter((app) => app.slug === appSlug)[0];

View on GitHub (pinned to 176037d0af)

Solutions

  1. Match the slug exactly to the constants ZOOM or OFFICE_365_VIDEO from @calcom/platform-constants.
  2. Confirm the redirect URI template in Zoom/Microsoft uses the same lowercase slug Cal.com uses.
  3. For Google Meet, use POST /v2/conferencing/google_meet/connect, not the OAuth callback.
  4. When surfacing the error, read the second argument (error cause) to get the full valid-app list.

Example fix

// before: client hardcodes slug
window.location = `/v2/conferencing/Zoom/oauth/callback?...`;

// after
import { ZOOM } from '@calcom/platform-constants';
window.location = `/v2/conferencing/${ZOOM}/oauth/callback?...`;
Defensive patterns

Strategy: type-guard

Validate before calling

import { ZOOM, OFFICE_365_VIDEO } from '@calcom/platform-constants';
const OAUTH_CONNECT_APPS = [ZOOM, OFFICE_365_VIDEO];

function validateOauthConnectApp(app: string): void {
  if (!OAUTH_CONNECT_APPS.includes(app)) {
    throw new Error(`${app} is not an OAuth-connectable app. Valid: ${OAUTH_CONNECT_APPS.join(', ')}`);
  }
}

validateOauthConnectApp(req.params.app);

Type guard

import { ZOOM, OFFICE_365_VIDEO } from '@calcom/platform-constants';
const OAUTH_CONNECT_APPS = [ZOOM, OFFICE_365_VIDEO] as const;
type OauthConnectApp = typeof OAUTH_CONNECT_APPS[number];

function isOauthConnectApp(app: string): app is OauthConnectApp {
  return (OAUTH_CONNECT_APPS as readonly string[]).includes(app);
}

Try / catch

try {
  await conferencingService.connectOauthApps(app, code, state);
} catch (e) {
  if (e instanceof BadRequestException && /Invalid conferencing app/.test(e.message)) {
    return res.status(400).json({ code: 'invalid_app', supported: [ZOOM, OFFICE_365_VIDEO] });
  }
  throw e;
}

Prevention

When it happens

Trigger: OAuth callback invoked with app=google_meet (Google Meet does not use OAuth connect — see error 92), app=cal_video (built-in, no connect), or any unknown slug. Also if the app param is URL-decoded incorrectly.

Common situations: Provider app console redirect URI uses a different slug than Cal.com expects; client reused a callback URL for a different app; slug casing mismatch (Zoom vs zoom).

Related errors


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