calcom/cal.diy · info · BadRequestException
Google Meet is already connected for this user.
Error message
Google Meet is already connected for this user.
What it means
Thrown by GoogleMeetService.connectGoogleMeetToUser when conferencingRepository.findGoogleMeet(userId) returns an existing credential — the user already has a google_meet credential row. Returns HTTP 400 via BadRequestException. Connecting again would create a duplicate; the existing credential is reused. Reached via POST /v2/conferencing/google_meet/connect → connectUserNonOauthApp.
Source
Thrown at apps/api/v2/src/modules/conferencing/services/google-meet.service.ts:22
import { Injectable } from "@nestjs/common";
import { GOOGLE_CALENDAR_TYPE, GOOGLE_MEET_TYPE } from "@calcom/platform-constants";
@Injectable()
export class GoogleMeetService {
private logger = new Logger("GoogleMeetService");
constructor(
private readonly conferencingRepository: ConferencingRepository,
private readonly credentialsRepository: CredentialsRepository
) {}
async connectGoogleMeetToUser(userId: number) {
await this.validateGoogleCalendarConnection(userId, "user");
const googleMeetExists = await this.conferencingRepository.findGoogleMeet(userId);
if (googleMeetExists) {
throw new BadRequestException("Google Meet is already connected for this user.");
}
return this.credentialsRepository.upsertUserAppCredential(GOOGLE_MEET_TYPE, {}, userId);
}
async connectGoogleMeetToTeam(teamId: number) {
await this.validateGoogleCalendarConnection(teamId, "team");
const googleMeetExists = await this.credentialsRepository.findCredentialByTypeAndTeamId(
GOOGLE_MEET_TYPE,
teamId
);
if (googleMeetExists) {
throw new BadRequestException("Google Meet is already connected for this team.");
}
return this.credentialsRepository.upsertTeamAppCredential(GOOGLE_MEET_TYPE, {}, teamId);
}View on GitHub (pinned to 176037d0af)
Solutions
- Before calling connect, check GET /v2/conferencing — if google_meet is listed, skip the connect call.
- Disable the connect button immediately on click (debounce) to prevent double-submit.
- Treat this 400 as success-equivalent in the client (idempotent connect) since the end state — Google Meet connected — is achieved.
- If you want true idempotency, switch the service to upsert instead of throw on duplicate.
Example fix
// before
await api.connectConferencing('google_meet');
// after
const installed = await api.listConferencingApps();
if (!installed.data.some(a => a.slug === 'google_meet')) {
await api.connectConferencing('google_meet');
} else {
showToast('Google Meet is already connected.');
} Defensive patterns
Strategy: validation
Validate before calling
async function googleMeetAlreadyConnected(conferencingRepository: ConferencingRepository, userId: number): Promise<boolean> {
return Boolean(await conferencingRepository.findGoogleMeet(userId));
}
if (await googleMeetAlreadyConnected(conferencingRepository, userId)) {
return { status: 'already_connected', app: 'google_meet' };
} Type guard
function isGoogleMeetCredential<T extends { type: string }>(c: T | null): c is T & { type: 'google_meet' } {
return c !== null && c.type === 'google_meet';
} Try / catch
try {
await googleMeetService.connectGoogleMeetToUser(userId);
} catch (e) {
if (e instanceof BadRequestException && /already connected/i.test(e.message)) {
// idempotent — treat as success
return { status: 'already_connected' };
}
throw e;
} Prevention
- Disable the connect button client-side immediately on click.
- Check GET /v2/conferencing for google_meet before offering the connect action.
- Treat the 'already connected' 400 as success-equivalent to make connect idempotent.
- Refresh the installed-apps list after a successful connect to keep UI state accurate.
When it happens
Trigger: User clicks 'Connect Google Meet' a second time; the frontend did not refresh its connected-apps state after the first connect; a retry fired because the first response was slow.
Common situations: UI button stays enabled after connect; double-submit (no debounce); race between two connect clicks; the connect succeeded but the response was lost and the client retried.
Related errors
- Invalid conferencing app. Available apps: GOOGLE_MEET.
- Google Meet is already connected for this team.
- Invalid conferencing app, available apps are:
- Invalid app, available apps are:
- ${appSlug} not connected.
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/95cf2cedc845383a.
Report an issue: GitHub.