bitwarden/server · error · BadRequestException
The specified sponsored organization could not be found unde
Error message
The specified sponsored organization could not be found under the given sponsoring organization.
What it means
Thrown by the admin-initiated DELETE /sponsorships/{organizationId}/{sponsoredFriendlyName}/revoke when no sponsorship under the sponsoring org has a FriendlyName matching sponsoredFriendlyName (case-insensitive). The caller has ManageUsers authorization, the sponsoring org exists, but the named sponsorship does not.
Source
Thrown at src/Api/Controllers/SelfHosted/SelfHostedOrganizationSponsorshipsController.cs:100
await _revokeSponsorshipCommand.RevokeSponsorshipAsync(existingOrgSponsorship);
}
[HttpPost("{sponsoringOrgId}/delete")]
[Obsolete("This endpoint is deprecated. Use DELETE /{sponsoringOrgId} instead.")]
public async Task PostRevokeSponsorship(Guid sponsoringOrgId)
{
await RevokeSponsorship(sponsoringOrgId);
}
[Authorize<ManageUsersRequirement>]
[HttpDelete("{organizationId}/{sponsoredFriendlyName}/revoke")]
public async Task AdminInitiatedRevokeSponsorshipAsync([FromRoute(Name = "organizationId")] Guid sponsoringOrgId, string sponsoredFriendlyName)
{
var sponsorships = await _organizationSponsorshipRepository.GetManyBySponsoringOrganizationAsync(sponsoringOrgId);
var existingOrgSponsorship = sponsorships.FirstOrDefault(s => s.FriendlyName != null && s.FriendlyName.Equals(sponsoredFriendlyName, StringComparison.OrdinalIgnoreCase));
if (existingOrgSponsorship == null)
{
throw new BadRequestException("The specified sponsored organization could not be found under the given sponsoring organization.");
}
await _revokeSponsorshipCommand.RevokeSponsorshipAsync(existingOrgSponsorship);
}
[Authorize("Application")]
[HttpGet("{orgId}/sponsored")]
public async Task<ListResponseModel<OrganizationSponsorshipInvitesResponseModel>> GetSponsoredOrganizations(Guid orgId)
{
var sponsoringOrg = await _organizationRepository.GetByIdAsync(orgId);
if (sponsoringOrg == null)
{
throw new NotFoundException();
}
var authorizationResult = await _authorizationService.AuthorizeAsync(User, orgId, new ManageUsersRequirement());
if (!authorizationResult.Succeeded)
{
throw new UnauthorizedAccessException();View on GitHub (pinned to e93b962371)
Solutions
- List sponsorships for the org (GET .../{orgId}/sponsored) and copy the exact current FriendlyName.
- Trim whitespace from the friendly name before sending.
- If already revoked, no action is needed; surface that state to the operator.
Example fix
// before: guessed friendly name
// DELETE /sponsorships/{orgId}/{guessedName}/revoke
//
// after: look up the exact friendly name first
var sponsored = (await GetSponsoredOrganizations(orgId))
.First(s => string.Equals(s.FriendlyName, nameWanted, StringComparison.OrdinalIgnoreCase));
await AdminRevokeAsync(orgId, sponsored.FriendlyName); Defensive patterns
Strategy: validation
Validate before calling
// Look up the exact FriendlyName before admin-initiated revoke
const sponsored = await getSponsoredOrganizations(orgId);
const match = sponsored.find(s => (s.friendlyName ?? '').trim().toLowerCase() === name.trim().toLowerCase());
if (!match) throw new Error('No sponsorship with that friendly name');
await adminRevoke(orgId, match.friendlyName); Type guard
function isMatchingFriendlyName(sponsored, name) {
return Array.isArray(sponsored) && sponsored.some(s =>
typeof s.friendlyName === 'string' &&
s.friendlyName.trim().toLowerCase() === String(name).trim().toLowerCase());
} Try / catch
try {
await adminRevoke(orgId, friendlyName);
} catch (e) {
if (e.status === 400 && /could not be found/i.test(e.message)) {
await refreshSponsorshipListAndPrompt(orgId);
} else throw e;
} Prevention
- Fetch the current sponsored list and copy the exact FriendlyName.
- Trim and case-normalize the friendly name client-side.
- Handle the already-revoked case explicitly in the UI.
When it happens
Trigger: Revoke with a friendly name that has a typo, has been renamed, was already revoked/deleted, or differs in case beyond what OrdinalIgnoreCase covers (it does cover case). Sponsored org may exist under a different friendly name.
Common situations: Admin copy-pastes a stale friendly name from an old list; the sponsorship was already revoked in another session; friendly name has trailing spaces stored; rename of the sponsored org changed FriendlyName.
Related errors
- Unknown Organization User
- Invalid license
- ExternalId cannot exceed 300 characters.
- ExternalId cannot exceed 300 characters.
- result.AsError.Message
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/6f61e6aeca1daa32.
Report an issue: GitHub.