{"record":{"id":"19439327511d3e43","repo":"calcom/cal.diy","slug":"event-operations-for-this-connection-are-currently","errorCode":null,"errorMessage":"Event operations for this connection are currently only available for Google Calendar","messagePattern":"Event operations for this connection are currently only available for Google Calendar","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"apps/api/v2/src/modules/cal-unified-calendars/services/google-calendar.service.ts","lineNumber":199,"sourceCode":"    }\n    return this.getAuthorizedCalendarInstance(\n      credential.user?.email ?? undefined,\n      credential.key,\n      credential.delegationCredentialId ? { id: credential.delegationCredentialId } : null\n    );\n  }\n\n  /**\n   * Gets an authorized Google Calendar instance for a specific credential (connection).\n   * Tries delegated auth first (if available), then falls back to direct OAuth.\n   */\n  async getCalendarClientByCredentialId(userId: number, credentialId: number): Promise<calendar_v3.Calendar> {\n    const credential = await this.credentialsRepository.findCredentialByIdAndUserId(credentialId, userId);\n    if (!credential) {\n      throw new NotFoundException(\"Calendar connection not found\");\n    }\n    if (credential.type !== GOOGLE_CALENDAR_TYPE) {\n      throw new BadRequestException(\n        \"Event operations for this connection are currently only available for Google Calendar\"\n      );\n    }\n    if (credential.invalid) {\n      throw new UnauthorizedException(\"Calendar credentials are invalid. Please reconnect.\");\n    }\n    return this.getAuthorizedCalendarInstance(\n      credential.user?.email ?? undefined,\n      credential.key,\n      credential.delegationCredentialId ? { id: credential.delegationCredentialId } : null\n    );\n  }\n\n  // ─── Shared private helpers (DRY calendar CRUD) ──────────────────────\n\n  private async listEventsWithClient(\n    calendar: calendar_v3.Calendar,\n    calendarId: string,","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/cal-unified-calendars/services/google-calendar.service.ts#L181-L217","documentation":"Thrown by getCalendarClientByCredentialId when the resolved credential's type is not google_calendar. The connection-scoped event endpoints currently only implement Google Calendar, so an Office 365 or Apple credential is rejected with HTTP 400. This guards the connection-scoped path before attempting event CRUD.","triggerScenarios":"Client passes a connectionId that resolves to an office_365_calendar or apple_calendar credential into the events endpoints (e.g. POST /v2/calendars/connections/{id}/events). Also happens if a future credential type slug is used.","commonSituations":"UI lists all connections uniformly but only Google supports event ops; user picks an Outlook connection from a dropdown; integration logic iterates all connections without filtering by type.","solutions":["Filter the connections list to type === google_calendar before offering event operations in the UI.","Call the connection list endpoint and map each to its supported capability set, disabling event actions for non-Google connections.","Track the roadmap for Office 365/Apple event support and surface an 'unsupported' state rather than issuing the request.","If Google is required, have the user connect Google Calendar and use that connectionId."],"exampleFix":"// before: client iterates all connections\nfor (const c of connections) {\n  await api.createEvent(c.connectionId, body);\n}\n\n// after\nfor (const c of connections) {\n  if (c.type !== 'google_calendar') continue; // skip unsupported providers\n  await api.createEvent(c.connectionId, body);\n}","handlingStrategy":"type-guard","validationCode":"import { GOOGLE_CALENDAR_TYPE } from '@calcom/platform-constants';\n\nasync function getGoogleConnectionForUser(userId: number): Promise<{ id: number }> {\n  const cred = await credentialsRepository.findCredentialByIdAndUserId(/* candidate */, userId);\n  if (!cred || cred.type !== GOOGLE_CALENDAR_TYPE) {\n    throw new BadRequestException('Operation requires a Google Calendar connection.');\n  }\n  return { id: cred.id };\n}","typeGuard":"import { GOOGLE_CALENDAR_TYPE } from '@calcom/platform-constants';\n\nfunction isGoogleCalendarType(c: { type: string } | null): c is { type: 'google_calendar' } {\n  return c !== null && c.type === GOOGLE_CALENDAR_TYPE;\n}","tryCatchPattern":"try {\n  await googleCalendarService.getEventByConnectionId(userId, credentialId, calId, evId);\n} catch (e) {\n  if (e instanceof BadRequestException && /only available for Google Calendar/.test(e.message)) {\n    return res.status(400).json({ code: 'unsupported_provider', supported: ['google_calendar'] });\n  }\n  throw e;\n}","preventionTips":["Filter the connections list by type on the client and only enable event actions for google_calendar.","Keep a single source of truth for provider capabilities in your integration layer.","Document per-connection which operations are supported to avoid trial-and-error API calls."],"tags":["google-calendar","office365","apple-calendar","validation","nestjs","provider"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}