toeverything/AFFiNE · error · OwnerCanNotLeaveWorkspace
owner_can_not_leave_workspace
owner_can_not_leave_workspace
Error message
Owner can not leave the workspace.
What it means
Thrown by `leaveWorkspace` when the caller is the workspace `Owner`. Workspaces must always retain an owner, so the owner cannot self-remove; ownership must be transferred first. Coded `owner_can_not_leave_workspace` (action_forbidden).
Source
Thrown at packages/backend/server/src/core/workspaces/resolvers/member.ts:770
nullable: true,
deprecationReason: 'no used anymore',
})
_sendLeaveMail?: boolean,
@Args('workspaceName', {
nullable: true,
deprecationReason: 'no longer used',
})
_workspaceName?: string
) {
const role = await this.models.workspaceUser.getActive(
workspaceId,
user.id
);
if (!role) {
throw new MemberNotFoundInSpace({ spaceId: workspaceId });
}
if (role.type === WorkspaceRole.Owner) {
throw new OwnerCanNotLeaveWorkspace();
}
await this.models.workspaceUser.delete(workspaceId, user.id);
this.event.emit('workspace.members.leave', {
workspaceId,
userId: user.id,
});
this.event.emit('workspace.members.updated', {
workspaceId,
});
await this.policy.reconcileWorkspaceQuotaState(workspaceId);
return true;
}
private async acceptInvitationByEmail(role: WorkspaceUserCompat) {
await this.assertWorkspaceAcceptsMemberChange(role.workspaceId);View on GitHub (pinned to 26c515e050)
Solutions
- Transfer ownership to another admin member first via the workspace settings UI, then leave.
- Disable the Leave control when `role === 'Owner'` and surface a 'transfer ownership first' message.
- If leaving permanently, assign a new owner and only then call `leaveWorkspace`.
- For workspaces with no other members, add a new owner before leaving or delete the workspace instead.
Example fix
// before
await sdk.leaveWorkspace({ workspaceId });
// after
if (myRole === 'Owner') {
notify('Transfer ownership to another member before leaving.');
openTransferOwnershipDialog();
return;
}
await sdk.leaveWorkspace({ workspaceId }); Defensive patterns
Strategy: validation
Validate before calling
// Block leave for owners
if (myRole === 'Owner') {
openTransferOwnershipDialog();
return;
}
await sdk.leaveWorkspace({ workspaceId }); Type guard
function isOwner(role) {
return role === 'Owner';
} Try / catch
try {
await sdk.leaveWorkspace({ workspaceId });
} catch (e) {
if (e.code === 'owner_can_not_leave_workspace') {
notify('Transfer ownership to another member before leaving.');
openTransferOwnershipDialog();
} else throw e;
} Prevention
- Disable the Leave control when the user's role is Owner.
- Always transfer ownership before attempting to leave.
- Surface the transfer-ownership flow proactively for sole owners.
When it happens
Trigger: The user whose `role.type === WorkspaceRole.Owner` calls `leaveWorkspace` on their own workspace. Common when the sole/last admin tries to leave without designating a successor.
Common situations: Founder/owner leaving the org without transferring ownership; UI does not distinguish owner from regular members in the leave action; script that bulk-leaves workspaces hits one the operator owns.
Related errors
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/bde269f0ada9f6cc.
Report an issue: GitHub.