{"record":{"id":"bc689b41ae742ee3","repo":"calcom/cal.diy","slug":"invalid-app-available-apps-are","errorCode":null,"errorMessage":"Invalid app, available apps are: ","messagePattern":"Invalid app, available apps are: ","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"apps/api/v2/src/modules/conferencing/services/conferencing.service.ts","lineNumber":92,"sourceCode":"          teamId\n        );\n\n      default:\n        throw new BadRequestException(\n          \"Invalid conferencing app, available apps are: \",\n          [ZOOM, OFFICE_365_VIDEO].join(\", \")\n        );\n    }\n  }\n\n  async getUserDefaultConferencingApp(userId: number) {\n    const user = await this.usersRepository.findById(userId);\n    return userMetadata.parse(user?.metadata)?.defaultConferencingApp;\n  }\n\n  async checkAppIsValidAndConnected(user: UserWithProfile, appSlug: string) {\n    if (!CONFERENCING_APPS.includes(appSlug)) {\n      throw new BadRequestException(\"Invalid app, available apps are: \", CONFERENCING_APPS.join(\", \"));\n    }\n    const credentials = await getUsersCredentialsIncludeServiceAccountKey(user);\n\n    const foundApp = getApps(credentials, true).filter((app) => app.slug === appSlug)[0];\n\n    const appLocation = foundApp?.appData?.location;\n\n    if (!foundApp || !appLocation) {\n      throw new BadRequestException(`${appSlug} not connected.`);\n    }\n    return foundApp.credential;\n  }\n\n  async disconnectConferencingApp(user: UserWithProfile, app: string) {\n    const credential = await this.checkAppIsValidAndConnected(user, app);\n    return handleDeleteCredential({\n      userId: user.id,\n      userMetadata: user?.metadata,","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/conferencing/services/conferencing.service.ts#L74-L110","documentation":"Thrown by ConferencingService.checkAppIsValidAndConnected when appSlug is not in the CONFERENCING_APPS array. This is the pre-flight validation used by disconnectConferencingApp and setDefaultConferencingApp. Returns HTTP 400. Like error 94 the message string ends mid-sentence and the full list is in the error-cause argument.","triggerScenarios":"Calling DELETE /v2/conferencing/{app}/disconnect or POST /v2/conferencing/{app}/default with an app slug not in CONFERENCING_APPS (e.g. 'webex', 'whereby', or a typo like 'daily').","commonSituations":"Client built before a slug rename; user typed a slug; integration lists third-party conferencing apps not supported by the platform API.","solutions":["Source the slug from the documented CONFERENCING_APPS constant or the GET /v2/conferencing list response.","Filter client-side dropdowns to only supported slugs.","Read the error-cause argument to surface the actual accepted list to the user.","Validate the slug against a known enum before issuing disconnect/default requests."],"exampleFix":"// before\nawait api.disconnectConferencing(userInputSlug);\n\n// after\nimport { CONFERENCING_APPS } from '@calcom/platform-constants';\nif (!CONFERENCING_APPS.includes(userInputSlug)) {\n  throw new UserError(`Unsupported conferencing app. Supported: ${CONFERENCING_APPS.join(', ')}`);\n}\nawait api.disconnectConferencing(userInputSlug);","handlingStrategy":"type-guard","validationCode":"import { CONFERENCING_APPS } from '@calcom/platform-constants';\n\nfunction validateConferencingAppSlug(slug: string): void {\n  if (!CONFERENCING_APPS.includes(slug)) {\n    throw new Error(`${slug} is not a supported conferencing app. Valid: ${CONFERENCING_APPS.join(', ')}`);\n  }\n}\n\nvalidateConferencingAppSlug(req.params.app);","typeGuard":"import { CONFERENCING_APPS } from '@calcom/platform-constants';\n\nfunction isConferencingApp(slug: string): slug is typeof CONFERENCING_APPS[number] {\n  return CONFERENCING_APPS.includes(slug);\n}","tryCatchPattern":"try {\n  await conferencingService.disconnectConferencingApp(user, app);\n} catch (e) {\n  if (e instanceof BadRequestException && /available apps are/.test(e.message)) {\n    return res.status(400).json({ code: 'invalid_app', supported: CONFERENCING_APPS });\n  }\n  throw e;\n}","preventionTips":["Populate dropdowns from GET /v2/conferencing so only valid slugs are offered.","Validate the slug client-side against CONFERENCING_APPS before issuing the request.","Surface the error-cause argument (valid app list) to the user when rejecting."],"tags":["conferencing","validation","nestjs","disconnect","default-app"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}