{"record":{"id":"19e48431aaa54f39","repo":"theonedev/onedev","slug":"root-user-cannot-be-deleted","errorCode":null,"errorMessage":"Root user cannot be deleted","messagePattern":"Root user cannot be deleted","errorType":"http","errorClass":"ExplicitException","httpStatus":400,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java","lineNumber":628,"sourceCode":"\n\t\tif (!getAuthUser().equals(user)) {\n\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","sourceCodeStart":610,"sourceCodeEnd":646,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java#L610-L646","documentation":"OneDev refuses to delete the root (built-in administrator) user via the REST deleteUser endpoint. The root account is a system bootstrap account and must always exist; deleting it would leave the instance potentially unadministrable. The DELETE call throws ExplicitException before userService.delete is invoked.","triggerScenarios":"Calling DELETE /users/{userId} with the id of the root user (User.isRoot()==true) as an administrator.","commonSituations":"Bulk user-cleanup scripts that don't exclude the root account; attempting to 'reset' an instance by deleting all users including root.","solutions":["Exclude the root user from deletion lists (skip users where isRoot is true)","If the root account needs to be locked down, rename it or disable password login instead of deleting","Never iterate 'delete all users' against an OneDev instance without filtering"],"exampleFix":"// before\nfor (long id : userIds) deleteUser(id);\n// after\nfor (long id : userIds) { User u = getUser(id); if (!u.isRoot()) deleteUser(id); }","handlingStrategy":"validation","validationCode":"User u = getUser(userId); if (u.isRoot()) throw new SkipException(\"refusing to delete root\");","typeGuard":"boolean isDeletable(User u) { return u != null && !u.isRoot(); }","tryCatchPattern":"try { deleteUser(userId); } catch (ExplicitException e) { log.warn(\"delete rejected: {}\", e.getMessage()); }","preventionTips":["Always exclude the root account from deletion lists","Use userId, not name matching, to identify the root account","Review bulk-cleanup scripts for unfiltered 'delete all' logic"],"tags":["rest-api","user-management","root-user"],"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-14T05:17:10.506Z"}