SonarSource/sonarqube · error · NotFoundException

User '%s' doesn't exist

Error message

User '%s' doesn't exist

What it means

The user update web service (api/users/update) throws this NotFoundException when the target login does not match an existing active user. Like other user WS actions, a deactivated user is indistinguishable from a missing one, so disabled accounts also produce this error. It prevents silently updating a non-existent account.

Source

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

  private void doHandle(DbSession dbSession, UpdateRequest request, UserDto userDto) {
    UpdateUser updateUser = new UpdateUser();
    if (request.getName() != null) {
      updateUser.setName(request.getName());
    }
    if (request.getEmail() != null) {
      updateUser.setEmail(emptyToNull(request.getEmail()));
    }
    if (!request.getScmAccounts().isEmpty()) {
      updateUser.setScmAccounts(request.getScmAccounts());
    }
    userUpdater.updateAndCommit(dbSession, userDto, updateUser, u -> {});
  }

  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;
  }

  private void writeUser(DbSession dbSession, Response response, String uuid) {
    try (JsonWriter json = response.newJsonWriter()) {
      json.beginObject();
      json.name("user");
      UserDto user = dbClient.userDao().selectByUuid(dbSession, uuid);
      checkState(user != null, "User with uuid '%s' doesn't exist", uuid);
      Set<String> groups = new HashSet<>(dbClient.groupMembershipDao().selectGroupsByLogins(dbSession, singletonList(uuid)).get(uuid));
      userWriter.write(json, user, groups, UserJsonWriter.FIELDS);
      json.endObject().close();
    }
  }

  private static UpdateRequest toWsRequest(Request request) {
    List<String> scmAccounts = parseScmAccounts(request);

View on GitHub (pinned to 184c821202)

Solutions

  1. Confirm the exact login via GET api/users/search?q=<term> as an administrator and use that login value.
  2. Reactivate deactivated users with POST api/users/update (active=true) or via Administration > Users before applying other changes.
  3. Create the user if it does not exist (POST api/users/create) before updating.
  4. Fix automation scripts to look up logins dynamically rather than hardcoding stale values.

Example fix

// before: hardcoded possibly-deactivated login
curl -u "$ADMIN:" -X POST 'https://sonar/api/users/update?login=bob&name=Robert'
// after: verify first, then update
LOGIN=$(curl -su "$ADMIN:" 'https://sonar/api/users/search?q=bob' | jq -r '.users[0].login')
curl -u "$ADMIN:" -X POST "https://sonar/api/users/update?login=$LOGIN&name=Robert"
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 update: ${login} missing or inactive`);

Type guard

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

Try / catch

try {
  await updateUser(login, changes);
} catch (e) {
  if (e.status === 404 && /doesn't exist/.test(e.message)) {
    // refresh login list / reactivate user, then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: POST api/users/update with login=<login> where selectByLogin returns null or the user has active=false.

Common situations: Typo in login; user deactivated before the update script ran; updating via email or display name instead of login; user deleted between listing and updating (race); provisioning delays for SSO users.

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/5e0a99fba2bbc6e5. Report an issue: GitHub.