toeverything/AFFiNE · warning · CannotDeleteOwnAccount
cannot_delete_own_account
cannot_delete_own_account
Error message
Cannot delete own account.
What it means
The admin deleteUser mutation refuses to delete the caller's own account (user.id === id) as a deliberate guardrail; self-deletion must go through the deleteAccount mutation instead, which also cleans up the caller's own session expectations.
Solutions
- Use the deleteAccount mutation (account settings) to delete your own account
- In admin UIs, disable or hide the delete action for the current admin's own row
- Filter the acting admin's id out of bulk-delete automation
Example fix
// before
await deleteUser({ id: targetId }); // 400 when targetId === me
// after
if (targetId === me.id) {
await deleteAccount(); // self-deletion path
} else {
await deleteUser({ id: targetId });
} Defensive patterns
Strategy: validation
Validate before calling
// guard the admin panel action
function canDelete(targetId: string, currentAdminId: string): boolean {
return targetId !== currentAdminId;
} Type guard
function isSelfDeletion(targetId: string, currentUserId: string): boolean {
return targetId === currentUserId;
} Try / catch
try {
await deleteUser(id);
} catch (e) {
if (e?.extensions?.code === 'CANNOT_DELETE_OWN_ACCOUNT') redirectToDeleteAccount();
else throw e;
} Prevention
- Visually mark and disable self-row delete actions in admin UIs
- Route self-deletion to the deleteAccount mutation by design
- Exclude the acting admin's id from bulk user-management automation
When it happens
Trigger: An administrator opens user management and deletes their own row; bulk automation iterating user ids including the acting admin's id.
Common situations: Single-admin instances testing the feature on themselves; admin lists that do not visually distinguish the current admin's row.
Related errors
AI-assisted analysis of toeverything/AFFiNE@2af30773ae (2026-08-18).
Data as JSON: /api/errors/5313563918e22785.
Report an issue: GitHub.
Appendix: source
Thrown at packages/backend/server/src/core/user/resolver.ts:387
return sessionUser(result.value);
} else {
return {
email: input.users[i].email,
error: result.reason.message,
};
}
});
}
@Mutation(() => DeleteAccount, {
description: 'Delete a user account',
})
async deleteUser(
@CurrentUser() user: CurrentUser,
@Args('id') id: string
): Promise<DeleteAccount> {
if (user.id === id) {
throw new CannotDeleteOwnAccount();
}
await this.models.user.delete(id);
return { success: true };
}
@Mutation(() => UserType, {
description: 'Update an user',
})
async updateUser(
@Args('id') id: string,
@Args('input') input: ManageUserInput
): Promise<UserType> {
const user = await this.db.user.findUnique({
where: { id },
});
if (!user) {
throw new UserNotFound();View on GitHub (pinned to 2af30773ae)