SonarSource/sonarqube · error · IllegalArgumentException
User ' ' is not deactivated
Error message
User '%s' is not deactivated
What it means
api/users/anonymize only works on deactivated users: AnonymizeAction.handle loads the user by login and throws IllegalArgumentException if user.isActive(), because anonymizing an active user would break their sessions/assignments expectations. The user record is untouched when this fires.
Solutions
- Call POST api/users/deactivate?login=x first, then anonymize
- Check the user's active=false status (api/users/search) before anonymizing
- If the user was re-activated by mistake, deactivate again before retrying
Example fix
// before POST /api/users/anonymize?login=jdoe // after POST /api/users/deactivate?login=jdoe POST /api/users/anonymize?login=jdoe
Defensive patterns
Strategy: validation
Validate before calling
const user = await getUser(login);
if (user.active) throw new Error(`Deactivate user '${login}' before anonymizing`); Type guard
function canAnonymize(user) { return user != null && user.active === false; } Try / catch
try { await anonymizeUser(login); } catch (e) { if (/is not deactivated/.test(e.message)) { await deactivateUser(login); return anonymizeUser(login); } throw e; } Prevention
- Always pair anonymize with a preceding deactivate call
- Check user.active via api/users/search before anonymizing
- Guard re-activation workflows so anonymized users are never re-enabled
When it happens
Trigger: POST api/users/anonymize?login=x where the user exists but is still active (has not been deactivated via api/users/deactivate).
Common situations: Admin scripts skipping the deactivate step; SCIM/automation assuming anonymize implies deactivation; retrying anonymize for a user that was re-activated.
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
- new_password_same_as_old
- old_password_incorrect
- The ' ' parameter is missing
- Already started
- Cannot change the assignee of this hotspot given its…
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/63c83359c5c8b49a.
Report an issue: GitHub.
Appendix: source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/AnonymizeAction.java:73
.setDeprecatedSince("10.4")
.setChangelog(new Change("10.4", "Deprecated. Use DELETE api/v2/users-management/users/{id}?anonymize=true instead"));
action.createParam(PARAM_LOGIN)
.setDescription("User login")
.setRequired(true)
.setExampleValue("myuser");
}
@Override
public void handle(Request request, Response response) throws Exception {
userSession.checkLoggedIn().checkIsSystemAdministrator();
String login = request.mandatoryParam(PARAM_LOGIN);
try (DbSession dbSession = dbClient.openSession(false)) {
UserDto user = dbClient.userDao().selectByLogin(dbSession, login);
checkFound(user, "User '%s' doesn't exist", login);
if (user.isActive()) {
throw new IllegalArgumentException(String.format("User '%s' is not deactivated", login));
}
userAnonymizer.anonymize(dbSession, user);
dbClient.userDao().update(dbSession, user);
dbSession.commit();
}
response.noContent();
}
}
View on GitHub (pinned to 184c821202)