theonedev/onedev · error · ExplicitException
Cannot delete yourself
Error message
Cannot delete yourself
What it means
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.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java:630
var newAuditContent = VersionedXmlDoc.fromBean(sshKey).toXML();
auditService.audit(null, "added ssh key to account \"" + user.getName() + "\" via RESTful API", null, newAuditContent);
}
return sshKey.getId();
}
@Api(order=2300)
@Path("/{userId}")
@DELETE
public Response deleteUser(@PathParam("userId") Long userId) {
if (!SecurityUtils.isAdministrator())
throw new UnauthorizedException();
User user = userService.load(userId);
if (user.isRoot())
throw new ExplicitException("Root user cannot be deleted");
else if (user.equals(getAuthUser()))
throw new ExplicitException("Cannot delete yourself");
else
userService.delete(user);
var oldAuditContent = VersionedXmlDoc.fromBean(getData(user)).toXML();
auditService.audit(null, "deleted account \"" + user.getName() + "\" via RESTful API", oldAuditContent, null);
return Response.ok().build();
}
public static class UserData implements Serializable {
private static final long serialVersionUID = 1L;
@Api(order=5, description="ID of the user")
private Long id;
@Api(order=10, description="Whether or not the user is disabled")
private boolean disabled;View on GitHub (pinned to d44925c47c)
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
Example fix
// before for (long id : userIds) deleteUser(id); // after long me = getAuthenticatedUserId(); for (long id : userIds) if (id != me) deleteUser(id);
Defensive patterns
Strategy: validation
Validate before calling
User me = getUser("me"); if (targetUserId.equals(me.getId())) throw new SkipException("cannot delete self"); Type guard
boolean isSelf(User target, User authUser) { return target != null && target.equals(authUser); } Try / catch
try { deleteUser(userId); } catch (ExplicitException e) { if (e.getMessage().contains("yourself")) log.warn("skipped own account"); } Prevention
- 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
When it happens
Trigger: Calling DELETE /users/{userId} where userId equals the authenticated admin's own user id.
Common situations: Admin cleaning up stale accounts whose list accidentally includes their own account; scripts authenticating as the very user they intend to delete.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Should only enable normal users
- Should only convert normal users to service accounts
- Cannot set queries and watches for disabled user
- Cannot set queries and watches for service or ai account
- Root user cannot be deleted
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/5f003ee857c52e08.
Report an issue: GitHub.