{"record":{"id":"e4a484fd8bc91fe7","repo":"bitwarden/server","slug":"can-only-revoke-a-sponsorship-you-granted","errorCode":null,"errorMessage":"Can only revoke a sponsorship you granted.","messagePattern":"Can only revoke a sponsorship you granted\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Billing/Controllers/OrganizationSponsorshipsController.cs","lineNumber":239,"sourceCode":"        {\n            throw new BadRequestException(\"Invalid Billing Sync Key\");\n        }\n\n        var (syncResponseData, offersToSend) = await _syncSponsorshipsCommand.SyncOrganization(sponsoringOrg, model.ToOrganizationSponsorshipSync().SponsorshipsBatch);\n        await _sendSponsorshipOfferCommand.BulkSendSponsorshipOfferAsync(sponsoringOrg.DisplayName(), offersToSend);\n        return new OrganizationSponsorshipSyncResponseModel(syncResponseData);\n    }\n\n    [Authorize(\"Application\")]\n    [HttpDelete(\"{sponsoringOrganizationId}\")]\n    [SelfHosted(NotSelfHostedOnly = true)]\n    public async Task RevokeSponsorship(Guid sponsoringOrganizationId)\n    {\n\n        var orgUser = await _organizationUserRepository.GetByOrganizationAsync(sponsoringOrganizationId, _currentContext.UserId ?? default);\n        if (_currentContext.UserId != orgUser?.UserId)\n        {\n            throw new BadRequestException(\"Can only revoke a sponsorship you granted.\");\n        }\n\n        var existingOrgSponsorship = await _organizationSponsorshipRepository\n            .GetBySponsoringOrganizationUserIdAsync(orgUser.Id);\n\n        await _revokeSponsorshipCommand.RevokeSponsorshipAsync(existingOrgSponsorship);\n    }\n\n    [Authorize(\"Application\")]\n    [HttpPost(\"{sponsoringOrganizationId}/delete\")]\n    [Obsolete(\"This endpoint is deprecated. Use DELETE /{sponsoringOrganizationId} instead.\")]\n    [SelfHosted(NotSelfHostedOnly = true)]\n    public async Task PostRevokeSponsorship(Guid sponsoringOrganizationId)\n    {\n        await RevokeSponsorship(sponsoringOrganizationId);\n    }\n\n    [Authorize(\"Application\")]","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Billing/Controllers/OrganizationSponsorshipsController.cs#L221-L257","documentation":"Thrown (HTTP 400) on DELETE /{sponsoringOrganizationId} when the current user's id does not equal the org user's UserId (or orgUser is null). Only the specific org member who originally granted the sponsorship may revoke it via this endpoint.","triggerScenarios":"A different admin than the original granter attempts the revoke; orgUser is null because the current user is not a member of that org; the original granter's membership was removed.","commonSituations":"Original granter left the org; multiple admins and a non-granter tries to revoke.","solutions":["Have the original granting org user perform the revoke.","Use the admin-initiated revoke endpoint (DELETE .../{organizationId}/{sponsoredFriendlyName}/revoke) which requires ManageUsers instead.","Confirm the current user is still a member of the sponsoring org."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm the current user is the org member who granted the sponsorship before calling revoke.\nconst orgUser = await getOrgUser(sponsoringOrgId, currentUserId);\nif (!orgUser || orgUser.userId !== currentUserId) {\n  throw new Error('Only the granting user can revoke this sponsorship');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await del(`/organization-sponsorships/${sponsoringOrgId}`);\n} catch (e) {\n  if (e.isBadRequest && /sponsorship you granted/i.test(e.message)) {\n    routeToAdminRevokeEndpoint(); // use the ManageUsers admin-initiated revoke instead\n  } else { throw e; }\n}","preventionTips":["Determine whether the current user is the original granter before showing self-service revoke.","Offer the admin-initiated revoke endpoint to org admins with ManageUsers.","Track which org user granted each sponsorship in the UI."],"tags":["billing","sponsorship","authorization","organization"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}