{"record":{"id":"6f61e6aeca1daa32","repo":"bitwarden/server","slug":"the-specified-sponsored-organization-could-not-be-6f61e6","errorCode":null,"errorMessage":"The specified sponsored organization could not be found under the given sponsoring organization.","messagePattern":"The specified sponsored organization could not be found under the given sponsoring organization\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Controllers/SelfHosted/SelfHostedOrganizationSponsorshipsController.cs","lineNumber":100,"sourceCode":"        await _revokeSponsorshipCommand.RevokeSponsorshipAsync(existingOrgSponsorship);\n    }\n\n    [HttpPost(\"{sponsoringOrgId}/delete\")]\n    [Obsolete(\"This endpoint is deprecated. Use DELETE /{sponsoringOrgId} instead.\")]\n    public async Task PostRevokeSponsorship(Guid sponsoringOrgId)\n    {\n        await RevokeSponsorship(sponsoringOrgId);\n    }\n\n    [Authorize<ManageUsersRequirement>]\n    [HttpDelete(\"{organizationId}/{sponsoredFriendlyName}/revoke\")]\n    public async Task AdminInitiatedRevokeSponsorshipAsync([FromRoute(Name = \"organizationId\")] Guid sponsoringOrgId, string sponsoredFriendlyName)\n    {\n        var sponsorships = await _organizationSponsorshipRepository.GetManyBySponsoringOrganizationAsync(sponsoringOrgId);\n        var existingOrgSponsorship = sponsorships.FirstOrDefault(s => s.FriendlyName != null && s.FriendlyName.Equals(sponsoredFriendlyName, StringComparison.OrdinalIgnoreCase));\n        if (existingOrgSponsorship == null)\n        {\n            throw new BadRequestException(\"The specified sponsored organization could not be found under the given sponsoring organization.\");\n        }\n        await _revokeSponsorshipCommand.RevokeSponsorshipAsync(existingOrgSponsorship);\n    }\n\n    [Authorize(\"Application\")]\n    [HttpGet(\"{orgId}/sponsored\")]\n    public async Task<ListResponseModel<OrganizationSponsorshipInvitesResponseModel>> GetSponsoredOrganizations(Guid orgId)\n    {\n        var sponsoringOrg = await _organizationRepository.GetByIdAsync(orgId);\n        if (sponsoringOrg == null)\n        {\n            throw new NotFoundException();\n        }\n\n        var authorizationResult = await _authorizationService.AuthorizeAsync(User, orgId, new ManageUsersRequirement());\n        if (!authorizationResult.Succeeded)\n        {\n            throw new UnauthorizedAccessException();","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Controllers/SelfHosted/SelfHostedOrganizationSponsorshipsController.cs#L82-L118","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: guessed friendly name\n//   DELETE /sponsorships/{orgId}/{guessedName}/revoke\n//\n// after: look up the exact friendly name first\nvar sponsored = (await GetSponsoredOrganizations(orgId))\n  .First(s => string.Equals(s.FriendlyName, nameWanted, StringComparison.OrdinalIgnoreCase));\nawait AdminRevokeAsync(orgId, sponsored.FriendlyName);","handlingStrategy":"validation","validationCode":"// Look up the exact FriendlyName before admin-initiated revoke\nconst sponsored = await getSponsoredOrganizations(orgId);\nconst match = sponsored.find(s => (s.friendlyName ?? '').trim().toLowerCase() === name.trim().toLowerCase());\nif (!match) throw new Error('No sponsorship with that friendly name');\nawait adminRevoke(orgId, match.friendlyName);","typeGuard":"function isMatchingFriendlyName(sponsored, name) {\n  return Array.isArray(sponsored) && sponsored.some(s =>\n    typeof s.friendlyName === 'string' &&\n    s.friendlyName.trim().toLowerCase() === String(name).trim().toLowerCase());\n}","tryCatchPattern":"try {\n  await adminRevoke(orgId, friendlyName);\n} catch (e) {\n  if (e.status === 400 && /could not be found/i.test(e.message)) {\n    await refreshSponsorshipListAndPrompt(orgId);\n  } else throw e;\n}","preventionTips":["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."],"tags":["sponsorships","self-hosted","admin","http-400","validation"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}