{"record":{"id":"cf9e4cb99722ebde","repo":"bitwarden/server","slug":"couldnotfindorganizationuser","errorCode":null,"errorMessage":"CouldNotFindOrganizationUser","messagePattern":"CouldNotFindOrganizationUser","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"bitwarden_license/src/Sso/Controllers/AccountController.cs","lineNumber":779,"sourceCode":"            user,\n            organization.Id,\n            user.Email);\n\n        if (orgUser != null)\n        {\n            // Invited is allowed at this point because we know the user is trying to accept an org invite.\n            EnforceAllowedOrgUserStatus(\n                orgUser.Status,\n                allowedStatuses: [\n                    OrganizationUserStatusType.Invited,\n                    OrganizationUserStatusType.Accepted,\n                    OrganizationUserStatusType.Confirmed,\n                ],\n                organization.DisplayName());\n        }\n        else\n        {\n            throw new Exception(_i18nService.T(\"CouldNotFindOrganizationUser\", user.Id, organization.Id));\n        }\n    }\n\n    private async Task<User?> GetUserFromManualLinkingDataAsync(string userIdentifier)\n    {\n        User? user = null;\n        var split = userIdentifier.Split(\",\");\n        if (split.Length < 2)\n        {\n            throw new Exception(_i18nService.T(\"InvalidUserIdentifier\"));\n        }\n\n        var userId = split[0];\n        var token = split[1];\n\n        var tokenOptions = new TokenOptions();\n\n        var claimedUser = await _userService.GetUserByIdAsync(userId);","sourceCodeStart":761,"sourceCodeEnd":797,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/bitwarden_license/src/Sso/Controllers/AccountController.cs#L761-L797","documentation":"Thrown in AccountController.PreventOrgUserLoginIfStatusInvalidAsync (line 779) after the resolved user has been signed in or is about to be. The method lazily resolves organization (from provider) and orgUser (by user+org or email). If orgUser is still null after all lookups, the user has no OrganizationUser record for this organization, which is an invalid state for SSO login.","triggerScenarios":"After the provisioning flow, PreventOrgUserLoginIfStatusInvalidAsync is called with a null orgUser. The lazy lookup by GetOrganizationUserByUserAndOrgIdOrEmailAsync (by user ID then by email) returns null, meaning no OrganizationUser exists for this user in this org.","commonSituations":"The OrganizationUser was deleted between provisioning and this check; the user's email changed so the email-based lookup fails; a race condition removed the membership; the provisioning path returned a user but not an orgUser and the lazy resolution fails.","solutions":["Verify the user has an active OrganizationUser record for the organization (check via admin portal or database).","If the membership was revoked or deleted, have an admin re-invite the user.","Investigate server logs for any deletion or status-change events that occurred during the SSO flow.","Check for email mismatches between the User record and OrganizationUser invite email."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before calling PreventOrgUserLoginIfStatusInvalidAsync, verify orgUser exists\nvar orgUser = await GetOrganizationUserByUserAndOrgIdOrEmailAsync(user, orgId, user.Email);\nif (orgUser == null)\n    return BadRequest($\"No organization user found for user {user.Id} in org {orgId}.\");","typeGuard":null,"tryCatchPattern":"try { await PreventOrgUserLoginIfStatusInvalidAsync(organization, provider, orgUser, user); }\ncatch (Exception ex) when (ex.Message.Contains(\"CouldNotFindOrganizationUser\"))\n{ /* log user.Id + org.Id; instruct admin to re-invite user */ }","preventionTips":["Ensure users have active org memberships before SSO login.","Monitor for org-user deletions that occur during active SSO sessions.","Keep User.Email and OrganizationUser invite email in sync."],"tags":["sso","authentication","organization","membership","data-integrity"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}