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
- Match the slug exactly to the constants ZOOM or OFFICE_365_VIDEO from @calcom/platform-constants.
- Confirm the redirect URI template in Zoom/Microsoft uses the same lowercase slug Cal.com uses.
- For Google Meet, use POST /v2/conferencing/google_meet/connect, not the OAuth callback.
- 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
- Source app slugs from the platform-constants package, not from literals.
- Verify the redirect URI template in the provider console uses the same slug casing.
- Read the error-cause argument (the second BadRequestException arg) to surface the full valid list.
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
- Missing `state` query param
- {error_description}
- Invalid conferencing app. Available apps: GOOGLE_MEET.
- ${responseBody.error}
- Event operations for this connection are currently only avai
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/464e5772eadfa2b7.
Report an issue: GitHub.