{"record":{"id":"ce75b02b94a133c6","repo":"calcom/cal.diy","slug":"office365-app-not-found","errorCode":null,"errorMessage":"Office365 app not found","messagePattern":"Office365 app not found","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"critical","filePath":"apps/api/v2/src/modules/conferencing/services/office365-video.service.ts","lineNumber":37,"sourceCode":"@Injectable()\nexport class Office365VideoService {\n  private logger = new Logger(\"Office365VideoService\");\n  private redirectUri = `${this.config.get(\"api.url\")}/conferencing/${OFFICE_365_VIDEO}/oauth/callback`;\n  private scopes = [\"OnlineMeetings.ReadWrite\", \"offline_access\"];\n\n  constructor(\n    private readonly config: ConfigService,\n    private readonly appsRepository: AppsRepository,\n    private readonly credentialsRepository: CredentialsRepository\n  ) {}\n\n  async getOffice365AppKeys() {\n    const app = await this.appsRepository.getAppBySlug(OFFICE_365_VIDEO);\n\n    const { client_id, client_secret } = zoomAppKeysSchema.parse(app?.keys);\n\n    if (!client_id) {\n      throw new NotFoundException(\"Office365 app not found\");\n    }\n\n    if (!client_secret) {\n      throw new NotFoundException(\"Office365 app not found\");\n    }\n\n    return { client_id, client_secret };\n  }\n\n  async generateOffice365AuthUrl(state: string) {\n    const { client_id } = await this.getOffice365AppKeys();\n\n    const params = {\n      response_type: \"code\",\n      client_id,\n      scope: this.scopes.join(\" \"),\n      redirect_uri: this.redirectUri,\n      state: state,","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/conferencing/services/office365-video.service.ts#L19-L55","documentation":"Thrown by Office365VideoService.getOffice365AppKeys when the Office365 video app's keys, parsed through zoomAppKeysSchema, yield a falsy client_id. The app is loaded via appsRepository.getAppBySlug(OFFICE_365_VIDEO); if its keys lack a client_id the service throws NotFoundException (HTTP 404). This is a server configuration error, not a per-user error.","triggerScenarios":"Any call that reaches getOffice365AppKeys (generateOffice365AuthUrl, connectOffice365App) when the Office365 app row in the database has empty/missing client_id in its keys JSON. The `if (!client_id)` branch fires.","commonSituations":"The Office365 conferencing app was never configured in the admin App Store; the app row exists but client_id/client_secret fields were left blank; env-staging missing the keys present in production; a re-import of app data dropped the keys.","solutions":["Open the admin App Store, find the Office365 video app, and set a valid client_id (Azure AD application ID).","Verify the app slug stored matches OFFICE_365_VIDEO constant exactly so getAppBySlug returns the right row.","Confirm the keys JSON shape matches zoomAppKeysSchema (requires client_id and client_secret)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const app = await appsRepository.getAppBySlug(OFFICE_365_VIDEO);\nconst keys = zoomAppKeysSchema.safeParse(app?.keys);\nif (!keys.success || !keys.data.client_id) {\n  throw new Error('Office365 app misconfigured: missing client_id. Configure it in the App Store.');\n}","typeGuard":"const hasClientId = (k: unknown): k is { client_id: string; client_secret: string } =>\n  typeof k === 'object' && k !== null && typeof (k as any).client_id === 'string' && !!(k as any).client_id;","tryCatchPattern":null,"preventionTips":["Add a startup health check that verifies all conferencing apps have required keys.","Gate the Office365 connect UI behind a config flag that is only on when keys are present.","Log which key is missing so ops can fix the right field."],"tags":["conferencing","office365","config","app-keys","not-found","nestjs"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}