SonarSource/sonarqube · error · NotFoundException

User '%s' doesn't exist

Error message

User '%s' doesn't exist

What it means

UpdateLoginAction (api/users/update_login) throws this NotFoundException when the current login does not identify an existing active user. Renaming a login requires resolving the old login first; deactivated or missing users are rejected identically. The new login must additionally be free of reserved characters.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/user/ws/UpdateLoginAction.java:98

  @Override
  public void handle(Request request, Response response) throws Exception {
    userSession.checkLoggedIn().checkIsSystemAdministrator();
    managedInstanceChecker.throwIfInstanceIsManaged();
    String login = request.mandatoryParam(PARAM_LOGIN);
    String newLogin = request.mandatoryParam(PARAM_NEW_LOGIN);
    try (DbSession dbSession = dbClient.openSession(false)) {
      UserDto user = getUser(dbSession, login);
      userUpdater.updateAndCommit(dbSession, user, new UpdateUser().setLogin(newLogin), u -> {
      });
      response.noContent();
    }
  }

  private UserDto getUser(DbSession dbSession, String login) {
    UserDto user = dbClient.userDao().selectByLogin(dbSession, login);
    if (user == null || !user.isActive()) {
      throw new NotFoundException(format("User '%s' doesn't exist", login));
    }
    return user;
  }

}

View on GitHub (pinned to 184c821202)

Solutions

  1. Look up the exact login with GET api/users/search before renaming; use the returned 'login' field verbatim.
  2. Reactivate the user via api/users/update (active=true) if it was disabled, then perform the rename.
  3. Skip/create the user as appropriate: POST api/users/create for missing accounts.
  4. Refresh the source-of-truth export so it reflects current SonarQube users instead of stale data.

Example fix

// before: renaming from a stale HR list
curl -su "$ADMIN:" -X POST 'https://sonar/api/users/update_login?login=j.smith&newLogin=jane.smith'
// after: verify login exists first
LOGIN=$(curl -su "$ADMIN:" 'https://sonar/api/users/search?q=j.smith' | jq -r '.users[0].login')
[ -n "$LOGIN" ] && curl -su "$ADMIN:" -X POST "https://sonar/api/users/update_login?login=$LOGIN&newLogin=jane.smith"
Defensive patterns

Strategy: validation

Validate before calling

const {users} = await fetch(`${base}/api/users/search?q=${encodeURIComponent(login)}`, {headers: auth}).then(r => r.json());
const user = users.find(u => u.login === login && u.active);
if (!user) throw new Error(`cannot rename ${login}: missing or inactive`);
if (!/^[^';"\\\\]+$/.test(newLogin)) throw new Error(`newLogin ${newLogin} contains reserved characters`);

Type guard

function isRenamableUser(u, login) {
  return u != null && u.login === login && u.active === true;
}

Try / catch

try {
  await updateLogin(login, newLogin);
} catch (e) {
  if (e.status === 404 && /doesn't exist/.test(e.message)) {
    skipped.push(login); // not present or deactivated
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: POST api/users/update_login with login=<old login> that matches no user row or an inactive user.

Common situations: Corporate rename scripts using stale HR exports; user deactivated after leave but still in the rename list; using email address as login; case or whitespace differences between directory and SonarQube login.

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/42e4bc1b335f135b. Report an issue: GitHub.