calcom/cal.diy · warning · BadRequestException
${appSlug} not connected.
Error message
${appSlug} not connected. What it means
Thrown by ConferencingService.checkAppIsValidAndConnected when the slug is valid but no connected credential with an app location is found for the user. Returns HTTP 400. Used by disconnectConferencingApp (cannot disconnect what is not connected) and setDefaultConferencingApp (cannot default to a non-connected app, except cal_video which is global).
Source
Thrown at apps/api/v2/src/modules/conferencing/services/conferencing.service.ts:101
}
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];
const appLocation = foundApp?.appData?.location;
if (!foundApp || !appLocation) {
throw new BadRequestException(`${appSlug} not connected.`);
}
return foundApp.credential;
}
async disconnectConferencingApp(user: UserWithProfile, app: string) {
const credential = await this.checkAppIsValidAndConnected(user, app);
return handleDeleteCredential({
userId: user.id,
userMetadata: user?.metadata,
credentialId: credential.id,
});
}
async setDefaultConferencingApp(user: UserWithProfile, app: string) {
// cal-video is global, so we can skip this check
if (app !== CAL_VIDEO) {
await this.checkAppIsValidAndConnected(user, app);
}View on GitHub (pinned to 176037d0af)
Solutions
- Refresh the installed-apps list via GET /v2/conferencing before offering disconnect/set-default actions.
- If the user expects it connected, have them reconnect via the OAuth flow.
- For setDefaultConferencingApp, cal_video bypasses this check — use cal_video if no app is connected.
- Investigate any credential rows missing appData.location as a data-integrity bug.
Example fix
// before
await api.setDefaultConferencing('zoom');
// after
const installed = await api.listConferencingApps();
const slugs = installed.data.map(a => a.slug);
if (!slugs.includes('zoom')) {
showToast('Connect Zoom first.'); return;
}
await api.setDefaultConferencing('zoom'); Defensive patterns
Strategy: validation
Validate before calling
async function isAppConnected(conferencingService: ConferencingService, user: UserWithProfile, appSlug: string): Promise<boolean> {
try {
await conferencingService.checkAppIsValidAndConnected(user, appSlug);
return true;
} catch (e) {
if (e instanceof BadRequestException && /not connected/.test(e.message)) return false;
throw e;
}
}
if (!(await isAppConnected(conferencingService, user, app))) {
return { code: 'app_not_connected', app };
} Type guard
interface InstalledApp { slug: string; credential?: { id: number } }
function isConnectedApp<T extends InstalledApp>(apps: T[], slug: string): apps is (T & { credential: { id: number } })[] {
return apps.some(a => a.slug === slug && Boolean(a.credential));
} Try / catch
try {
await conferencingService.setDefaultConferencingApp(user, app);
} catch (e) {
if (e instanceof BadRequestException && /not connected/.test(e.message)) {
return res.status(400).json({ code: 'app_not_connected', app });
}
throw e;
} Prevention
- Refresh the installed-apps list before exposing disconnect/set-default actions.
- Disable those actions in the UI when the app is not in the installed list.
- Use cal_video as a safe default-app fallback since it bypasses the connected check.
When it happens
Trigger: Calling DELETE /v2/conferencing/zoom/disconnect when the user never connected Zoom, or connected then deleted it; calling POST /v2/conferencing/zoom/default without a Zoom credential; the credential exists but its appData.location is missing (incomplete install).
Common situations: Stale UI showing an app as connected; user connected in a different account/tenant; app-store credential row missing location metadata after a partial install.
Related errors
- Calendar connection not found
- Calendar credentials are invalid. Please reconnect.
- Invalid conferencing app. Available apps: GOOGLE_MEET.
- Invalid conferencing app, available apps are:
- Invalid app, available apps are:
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/5869ff026a9fbc04.
Report an issue: GitHub.