{"record":{"id":"5313563918e22785","repo":"toeverything/AFFiNE","slug":"cannot-delete-own-account","errorCode":"cannot_delete_own_account","errorMessage":"Cannot delete own account.","messagePattern":"Cannot delete own account\\.","errorType":"exception","errorClass":"CannotDeleteOwnAccount","httpStatus":403,"severity":"warning","filePath":"packages/backend/server/src/core/user/resolver.ts","lineNumber":387,"sourceCode":"        return sessionUser(result.value);\n      } else {\n        return {\n          email: input.users[i].email,\n          error: result.reason.message,\n        };\n      }\n    });\n  }\n\n  @Mutation(() => DeleteAccount, {\n    description: 'Delete a user account',\n  })\n  async deleteUser(\n    @CurrentUser() user: CurrentUser,\n    @Args('id') id: string\n  ): Promise<DeleteAccount> {\n    if (user.id === id) {\n      throw new CannotDeleteOwnAccount();\n    }\n    await this.models.user.delete(id);\n    return { success: true };\n  }\n\n  @Mutation(() => UserType, {\n    description: 'Update an user',\n  })\n  async updateUser(\n    @Args('id') id: string,\n    @Args('input') input: ManageUserInput\n  ): Promise<UserType> {\n    const user = await this.db.user.findUnique({\n      where: { id },\n    });\n\n    if (!user) {\n      throw new UserNotFound();","sourceCodeStart":369,"sourceCodeEnd":405,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/2af30773aecd567f09b346e7b72fc69143144057/packages/backend/server/src/core/user/resolver.ts#L369-L405","documentation":"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.","triggerScenarios":"An administrator opens user management and deletes their own row; bulk automation iterating user ids including the acting admin's id.","commonSituations":"Single-admin instances testing the feature on themselves; admin lists that do not visually distinguish the current admin's row.","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"],"exampleFix":"// before\nawait deleteUser({ id: targetId }); // 400 when targetId === me\n\n// after\nif (targetId === me.id) {\n  await deleteAccount(); // self-deletion path\n} else {\n  await deleteUser({ id: targetId });\n}","handlingStrategy":"validation","validationCode":"// guard the admin panel action\nfunction canDelete(targetId: string, currentAdminId: string): boolean {\n  return targetId !== currentAdminId;\n}","typeGuard":"function isSelfDeletion(targetId: string, currentUserId: string): boolean {\n  return targetId === currentUserId;\n}","tryCatchPattern":"try {\n  await deleteUser(id);\n} catch (e) {\n  if (e?.extensions?.code === 'CANNOT_DELETE_OWN_ACCOUNT') redirectToDeleteAccount();\n  else throw e;\n}","preventionTips":["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"],"tags":["admin","user-management","guardrail","graphql"],"backgroundTag":"self-deletion-forbidden","analyzedSha":"2af30773aecd567f09b346e7b72fc69143144057","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}