{"record":{"id":"0d8965e26a05f6d2","repo":"bitwarden/server","slug":"there-already-exists-a-teams-integration-for-this","errorCode":null,"errorMessage":"There already exists a Teams integration for this organization","messagePattern":"There already exists a Teams integration for this organization","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"warning","filePath":"src/Api/Dirt/Controllers/TeamsIntegrationController.cs","lineNumber":62,"sourceCode":"        }\n\n        var integrations = await integrationRepository.GetManyByOrganizationAsync(organizationId);\n        var integration = integrations.FirstOrDefault(i => i.Type == IntegrationType.Teams);\n\n        if (integration is null)\n        {\n            // No teams integration exists, create Initiated version\n            integration = await integrationRepository.CreateAsync(new OrganizationIntegration\n            {\n                OrganizationId = organizationId,\n                Type = IntegrationType.Teams,\n                Configuration = null,\n            });\n        }\n        else if (integration.Configuration is not null)\n        {\n            // A Completed (fully configured) Teams integration already exists, throw to prevent overriding\n            throw new BadRequestException(\"There already exists a Teams integration for this organization\");\n\n        } // An Initiated teams integration exits, re-use it and kick off a new OAuth flow\n\n        var state = IntegrationOAuthState.FromIntegration(integration, timeProvider);\n        var redirectUrl = teamsService.GetRedirectUrl(\n            callbackUrl: callbackUrl,\n            state: state.ToString()\n        );\n\n        if (string.IsNullOrEmpty(redirectUrl))\n        {\n            throw new NotFoundException();\n        }\n\n        return Redirect(redirectUrl);\n    }\n\n    [HttpGet(\"integrations/teams/create\", Name = \"TeamsIntegration_Create\")]","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Dirt/Controllers/TeamsIntegrationController.cs#L44-L80","documentation":"Thrown during Teams OAuth initiation when a Teams integration already exists for the organization with non-null Configuration (fully completed). The controller blocks overriding a completed integration. BadRequestException returns HTTP 400.","triggerScenarios":"Initiating a new Teams OAuth flow for an org that already has a completed Teams integration. An 'Initiated' (Configuration == null) integration can be re-used, but a 'Completed' one triggers this error.","commonSituations":"Re-running Teams setup for an org that already completed configuration; duplicate setup attempts; admin wants to reconfigure Teams without removing the old integration first.","solutions":["Delete the existing completed Teams integration before initiating a new OAuth flow.","In the UI, detect an existing completed integration and show a 'Reconfigure' flow that deletes-then-recreates.","Check the integration list endpoint before presenting the connect option."],"exampleFix":"// before\nawait api.InitiateTeamsOAuthAsync(orgId); // 400 if already configured\n\n// after\nvar integrations = await api.GetOrganizationIntegrationsAsync(orgId);\nvar teams = integrations.FirstOrDefault(i => i.Type == \"Teams\");\nif (teams?.Configuration != null)\n{\n    await api.DeleteIntegrationAsync(orgId, teams.Id);\n}\nawait api.InitiateTeamsOAuthAsync(orgId);","handlingStrategy":"validation","validationCode":"var integrations = await integrationRepository.GetManyByOrganizationAsync(orgId);\nvar existing = integrations.FirstOrDefault(i => i.Type == IntegrationType.Teams);\nif (existing?.Configuration != null)\n    return Conflict(\"A completed Teams integration already exists. Delete it first to reconfigure.\");\n// safe to initiate","typeGuard":"public static bool HasCompletedTeamsIntegration(IEnumerable<OrganizationIntegration> integrations) =>\n    integrations.Any(i => i.Type == IntegrationType.Teams && i.Configuration != null);","tryCatchPattern":"try\n{\n    await _teamsService.InitiateOAuthAsync(orgId);\n}\ncatch (BadRequestException ex) when (ex.Message.Contains(\"already exists\"))\n{\n    return Conflict(ex.Message);\n}","preventionTips":["Check for existing completed integrations before presenting the connect option.","Implement a clean delete-then-recreate workflow for reconfiguration.","Show a clear UI state when a completed integration is already present."],"tags":["teams","oauth","integration","duplicate","configuration","csharp","aspnet"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}