{"record":{"id":"5f003ee857c52e08","repo":"theonedev/onedev","slug":"cannot-delete-yourself","errorCode":null,"errorMessage":"Cannot delete yourself","messagePattern":"Cannot delete yourself","errorType":"http","errorClass":"ExplicitException","httpStatus":400,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java","lineNumber":630,"sourceCode":"\t\t\tvar newAuditContent = VersionedXmlDoc.fromBean(sshKey).toXML();\n\t\t\tauditService.audit(null, \"added ssh key to account \\\"\" + user.getName() + \"\\\" via RESTful API\", null, newAuditContent);\n\t\t}\n\n\t\treturn sshKey.getId();\n\t}\n\t\n\t@Api(order=2300)\n\t@Path(\"/{userId}\")\n    @DELETE\n    public Response deleteUser(@PathParam(\"userId\") Long userId) {\n    \tif (!SecurityUtils.isAdministrator())\n\t\t\tthrow new UnauthorizedException();\n\n    \tUser user = userService.load(userId);\n    \tif (user.isRoot())\n\t\t\tthrow new ExplicitException(\"Root user cannot be deleted\");\n    \telse if (user.equals(getAuthUser()))\n    \t\tthrow new ExplicitException(\"Cannot delete yourself\");\n    \telse\n    \t\tuserService.delete(user);\n\n\t\tvar oldAuditContent = VersionedXmlDoc.fromBean(getData(user)).toXML();\n\t\tauditService.audit(null, \"deleted account \\\"\" + user.getName() + \"\\\" via RESTful API\", oldAuditContent, null);\n\n    \treturn Response.ok().build();\n    }\n\n\tpublic static class UserData implements Serializable {\n\n\t\tprivate static final long serialVersionUID = 1L;\n\t\t\n\t\t@Api(order=5, description=\"ID of the user\")\n\t\tprivate Long id;\n\n\t\t@Api(order=10, description=\"Whether or not the user is disabled\")\n\t\tprivate boolean disabled;","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java#L612-L648","documentation":"OneDev's deleteUser REST endpoint rejects deleting the currently authenticated user. This prevents an administrator from accidentally removing their own account, which would terminate their session and lock them out of the running deletion script. It is thrown as ExplicitException after the root check.","triggerScenarios":"Calling DELETE /users/{userId} where userId equals the authenticated admin's own user id.","commonSituations":"Admin cleaning up stale accounts whose list accidentally includes their own account; scripts authenticating as the very user they intend to delete.","solutions":["Run the deletion script under a service/admin account that is not in the deletion set","Filter the authenticated user's id out of the target list (compare against /users/me or the auth principal)","If you truly need the account gone, delete it from a different administrator session"],"exampleFix":"// before\nfor (long id : userIds) deleteUser(id);\n// after\nlong me = getAuthenticatedUserId();\nfor (long id : userIds) if (id != me) deleteUser(id);","handlingStrategy":"validation","validationCode":"User me = getUser(\"me\"); if (targetUserId.equals(me.getId())) throw new SkipException(\"cannot delete self\");","typeGuard":"boolean isSelf(User target, User authUser) { return target != null && target.equals(authUser); }","tryCatchPattern":"try { deleteUser(userId); } catch (ExplicitException e) { if (e.getMessage().contains(\"yourself\")) log.warn(\"skipped own account\"); }","preventionTips":["Run destructive scripts with a dedicated admin/service account not in the deletion set","Compare target ids against the authenticated principal first","Log skipped accounts for audit"],"tags":["rest-api","user-management","self-deletion"],"backgroundTag":"invalid-state-transition","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}