different-ai/openwork · error
Only the workspace owner can transfer ownership.
Error message
Only the workspace owner can transfer ownership.
What it means
transferOwnership is restricted to the current organization owner via access.canTransferOwnership. Any other member (including super-admins who are not the owner) throws "Only the workspace owner can transfer ownership." before target validation. Ownership transfer is a single-owner action by design.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_providers/org-dashboard-provider.tsx:720
ensureTargetIsNotOwner(memberId);
await runMutation("remove-member", async () => {
ensureActiveOrganizationSelected();
const { response, payload } = await requestJson(
`/v1/members/${encodeURIComponent(memberId)}`,
{ method: "DELETE" },
12000,
);
if (response.status !== 204 && !response.ok) {
throw getRequestError(payload, response, `Failed to remove member (${response.status}).`);
}
});
}
async function transferOwnership(memberId: string) {
if (!getCurrentAccess().canTransferOwnership) {
throw new Error("Only the workspace owner can transfer ownership.");
}
const target = ensureTargetIsNotOwner(memberId);
const targetAccess = getOrgAccessFlags(target?.role ?? "member", target?.isOwner ?? false, orgContext?.roles);
if (!target || !target.joinedAt || !targetAccess.isSuperAdmin) {
throw new Error("Ownership can only be transferred to an active super-admin.");
}
await runMutation("transfer-ownership", async () => {
ensureActiveOrganizationSelected();
const { response, payload } = await requestJson(
`/v1/members/${encodeURIComponent(memberId)}/transfer-ownership`,
{ method: "POST", body: JSON.stringify({}) },
12000,
);
if (!response.ok) {
throw getRequestError(payload, response, `Failed to transfer ownership (${response.status}).`);
}View on GitHub (pinned to 2b7df46e8a)
Solutions
- Have the current organization owner perform the transfer.
- Verify who the owner is on the Members screen (owner flag) before attempting.
- Refresh org context if ownership was recently transferred.
- Show the transfer control only to members whose access flags include canTransferOwnership.
Example fix
// before
<Button onClick={() => handleTransferOwnership(member.id)}>Make owner</Button>
// after
{access.canTransferOwnership && (
<Button onClick={() => handleTransferOwnership(member.id)}>Make owner</Button>
)} Defensive patterns
Strategy: validation
Validate before calling
if (!access.canTransferOwnership) return; // only the owner sees transfer controls
Try / catch
try {
await transferOwnership(memberId);
} catch (e) {
if (e instanceof Error && /transfer ownership|super-admin/.test(e.message)) {
toast(e.message);
} else throw e;
} Prevention
- Expose the transfer action only to the current owner.
- Show the owner flag in the member list so users know who can transfer.
- Refetch org context after any ownership change.
When it happens
Trigger: Calling transferOwnership(memberId) (e.g. from handleTransferOwnership) when the signed-in member is a super-admin or admin but not the organization owner, so canTransferOwnership is false.
Common situations: A super-admin assumes they can hand off ownership; an admin tries to resolve an owner leaving the team; the previous owner was already transferred and orgContext still lists the caller as owner.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- Only workspace owners and super-admins can change settings.
- Only the workspace owner can delete this organization.
- Only workspace admins can invite members.
- Only workspace admins can start seat checkout.
- Only workspace admins can cancel invitations.
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/23e8f894a3b1602c.
Report an issue: GitHub.