From cd53787c44c0501092f3ed093c395c59d7aa82f1 Mon Sep 17 00:00:00 2001 From: Jacek Date: Mon, 29 Jun 2026 16:17:08 -0500 Subject: [PATCH] fix(backend): guard deleteOrganization against empty organization ID deleteOrganization() was the only ID-based method on OrganizationAPI without a requireId() guard. Because joinPaths() drops falsy segments, deleteOrganization('') built the path /organizations and issued a DELETE to the collection route instead of failing fast locally. Add the guard so an empty ID throws 'A valid resource ID is required.' like its siblings. --- .changeset/delete-organization-require-id.md | 5 +++++ packages/backend/src/api/__tests__/OrganizationApi.test.ts | 6 ++++++ packages/backend/src/api/endpoints/OrganizationApi.ts | 2 ++ 3 files changed, 13 insertions(+) create mode 100644 .changeset/delete-organization-require-id.md diff --git a/.changeset/delete-organization-require-id.md b/.changeset/delete-organization-require-id.md new file mode 100644 index 00000000000..43cb092a00e --- /dev/null +++ b/.changeset/delete-organization-require-id.md @@ -0,0 +1,5 @@ +--- +'@clerk/backend': patch +--- + +`organizations.deleteOrganization()` now validates that an organization ID was provided. Calling it with an empty ID throws `A valid resource ID is required.` locally instead of issuing a `DELETE` request to the organizations collection endpoint, matching the other ID-based methods on the API. diff --git a/packages/backend/src/api/__tests__/OrganizationApi.test.ts b/packages/backend/src/api/__tests__/OrganizationApi.test.ts index 78510feb1a9..b8d7adfea74 100644 --- a/packages/backend/src/api/__tests__/OrganizationApi.test.ts +++ b/packages/backend/src/api/__tests__/OrganizationApi.test.ts @@ -185,6 +185,12 @@ describe('OrganizationAPI', () => { }); }); + describe('deleteOrganization', () => { + it('throws an error when the organization ID is missing', async () => { + await expect(apiClient.organizations.deleteOrganization('')).rejects.toThrow('A valid resource ID is required.'); + }); + }); + describe('createOrganizationInvitationBulk', () => { const mockInvitation = { object: 'organization_invitation', diff --git a/packages/backend/src/api/endpoints/OrganizationApi.ts b/packages/backend/src/api/endpoints/OrganizationApi.ts index 1f95786a3bd..fa3396871cf 100644 --- a/packages/backend/src/api/endpoints/OrganizationApi.ts +++ b/packages/backend/src/api/endpoints/OrganizationApi.ts @@ -361,6 +361,8 @@ export class OrganizationAPI extends AbstractAPI { } public async deleteOrganization(organizationId: string) { + this.requireId(organizationId); + return this.request({ method: 'DELETE', path: joinPaths(basePath, organizationId),