{"record":{"id":"a1badbb4bc53a25d","repo":"bitwarden/server","slug":"invalid-owner-owner-must-be-an-existing-bitwarden","errorCode":null,"errorMessage":"Invalid owner. Owner must be an existing Bitwarden user.","messagePattern":"Invalid owner\\. Owner must be an existing Bitwarden user\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"bitwarden_license/src/Commercial.Core/AdminConsole/Providers/CreateProviderCommand.cs","lineNumber":63,"sourceCode":"\n    public async Task CreateResellerAsync(Provider provider)\n    {\n        await ProviderRepositoryCreateAsync(provider, ProviderStatusType.Created);\n    }\n\n    public async Task CreateBusinessUnitAsync(Provider provider, string ownerEmail, PlanType plan, int minimumSeats)\n    {\n        var providerId = await CreateProviderAsync(provider, ownerEmail);\n\n        await CreateProviderPlanAsync(providerId, plan, minimumSeats);\n    }\n\n    private async Task<Guid> CreateProviderAsync(Provider provider, string ownerEmail)\n    {\n        var owner = await _userRepository.GetByEmailAsync(ownerEmail);\n        if (owner == null)\n        {\n            throw new BadRequestException(\"Invalid owner. Owner must be an existing Bitwarden user.\");\n        }\n\n        provider.Gateway = GatewayType.Stripe;\n\n        await ProviderRepositoryCreateAsync(provider, ProviderStatusType.Pending);\n\n        var providerUser = new ProviderUser\n        {\n            ProviderId = provider.Id,\n            UserId = owner.Id,\n            Type = ProviderUserType.ProviderAdmin,\n            Status = ProviderUserStatusType.Confirmed,\n        };\n\n        await _providerUserRepository.CreateAsync(providerUser);\n        await _providerService.SendProviderSetupInviteEmailAsync(provider, owner.Email);\n\n        return provider.Id;","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/bitwarden_license/src/Commercial.Core/AdminConsole/Providers/CreateProviderCommand.cs#L45-L81","documentation":"Thrown by the private CreateProviderAsync helper (used by CreateMspAsync and CreateBusinessUnitAsync) when IUserRepository.GetByEmailAsync(ownerEmail) returns null. A provider's owner must already be a registered Bitwarden user because a ProviderUser record (ProviderAdmin / Confirmed) is immediately created and bound to that user's Id. This is a BadRequestException mapping to HTTP 400.","triggerScenarios":"Calling CreateMspAsync or CreateBusinessUnitAsync with an ownerEmail that has no matching row in the Users table (typo, unregistered address, or wrong environment database).","commonSituations":"Seeding/automation scripts that reference an email not yet provisioned; integration tests against a fresh database; admin typos; email case differences depending on database collation.","solutions":["Verify the owner exists first: call _userRepository.GetByEmailAsync(ownerEmail) and confirm non-null before invoking the command.","Register/provision the user account before attempting provider creation.","Check you are pointed at the correct environment/database (dev vs staging)."],"exampleFix":"// before\nawait _createProviderCommand.CreateMspAsync(provider, \"notarealuser@example.com\", 10, 10);\n\n// after\nvar owner = await _userRepository.GetByEmailAsync(ownerEmail);\nif (owner == null) throw new InvalidOperationException($\"Owner {ownerEmail} is not a registered user.\");\nawait _createProviderCommand.CreateMspAsync(provider, ownerEmail, 10, 10);","handlingStrategy":"validation","validationCode":"var owner = await _userRepository.GetByEmailAsync(ownerEmail);\nif (owner == null)\n    throw new InvalidOperationException($\"No Bitwarden user found for owner email '{ownerEmail}'.\");","typeGuard":null,"tryCatchPattern":"try { await _createProviderCommand.CreateMspAsync(provider, ownerEmail, teams, enterprise); }\ncatch (BadRequestException ex) when (ex.Message.Contains(\"Invalid owner\"))\n{ /* surface: owner email is not a registered user */ }","preventionTips":["Always resolve the owner user by email before invoking provider creation.","In integration tests, seed the owner user fixture first.","Normalize email casing consistently between lookup and creation."],"tags":["provider","user-lookup","validation","create","bitwarden","csharp"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}