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's role type is WorkspaceRole.Owner. AFFiNE forbids the last controlling owner from abandoning a workspace via leave, because the workspace would be left ownerless.
Solutions
- Transfer ownership to another member first (workspace settings → transfer ownership), then leave as a regular member.
- If you want the workspace gone, delete the workspace instead of leaving it.
- If ownership transfer already happened, sign out/in or refresh the session so the updated role is used.
Defensive patterns
Strategy: validation
Validate before calling
// Before showing/calling leave, check the user's role in the workspace
const { workspace } = await gql.request(GET_WORKSPACE, { id: workspaceId });
if (workspace.permissions.role === 'Owner') {
// offer 'transfer ownership' or 'delete workspace' instead of leave
showOwnerLeaveGuard();
} else {
await gql.request(LEAVE_WORKSPACE, { workspaceId });
} Type guard
const isWorkspaceOwner = (role?: string): boolean => role === 'Owner';
Try / catch
try {
await leaveWorkspace(workspaceId);
} catch (e) {
if (getErrorCode(e) === 'owner_can_not_leave_workspace') {
openTransferOwnershipDialog(workspaceId);
}
} Prevention
- Hide the leave option for owners and offer ownership transfer / workspace deletion instead.
- In automation, never leave with the creator/owner identity; create a second admin member first.
When it happens
Trigger: The workspace owner account calls leaveWorkspace(workspaceId) for a workspace where its role.type === 'Owner'.
Common situations: Owner tries to leave during account cleanup or team handover; automation/test scripts that create a workspace and then try to leave it with the owner identity.
Related errors
- invalid_invitation
- authentication_required
- space_access_denied
- space_not_found
- workspace_id_required_to_update_team_subscription
AI-assisted analysis of toeverything/AFFiNE@4953682779 (2026-08-18).
Data as JSON: /api/errors/bde269f0ada9f6cc.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/core/workspaces/resolvers/member.ts:721
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 4953682779)