theonedev/onedev · error · NotAcceptableException

Multiple users found: ${userName}

Error message

Multiple users found: ${userName}

What it means

When userName matches multiple accounts (e.g. a full name shared by several users), the endpoint cannot disambiguate and throws NotAcceptableException("Multiple users found: <userName>"). This happens only after authentication succeeds and the primary lookups (by name, then full name) fell through to ambiguous full-name matching.

Source

Thrown at server-core/src/main/java/io/onedev/server/ai/TodResource.java:403

        User user;                
        if (userName != null) {
            user = userService.findByName(userName);
            if (user == null)
                user = userService.findByFullName(userName);
            if (user == null) {
                var matchingUsers = new ArrayList<User>();
                var lowerCaseUserName = userName.toLowerCase();
                for (var eachUser: userService.query()) {
                    if (eachUser.getFullName() != null) {
                        if (Splitter.on(" ").trimResults().omitEmptyStrings().splitToList(eachUser.getFullName().toLowerCase()).contains(lowerCaseUserName)) {
                            matchingUsers.add(eachUser);
                        }
                    }
                }
                if (matchingUsers.size() == 1) {
                    user = matchingUsers.get(0);
                } else if (matchingUsers.size() > 1) {
                    throw new NotAcceptableException("Multiple users found: " + userName);
                }
            }
            if (user == null) 
                throw new NotFoundException("User not found: " + userName);
        } else {
            user = SecurityUtils.getUser();
        }
        return user.getName();
    }

    @Path("/get-unix-timestamp")
    @GET
    public long getUnixTimestamp(@QueryParam("dateTimeDescription") @NotNull String dateTimeDescription) {
        if (SecurityUtils.getUser() == null)
            throw new UnauthenticatedException();

        return DateUtils.parseRelaxed(dateTimeDescription).getTime();
    }

View on GitHub (pinned to d44925c47c)

Solutions

  1. Pass the exact unique login name instead of a full name.
  2. List users (via admin user query) to find the unique login name and use that.
  3. Include more disambiguating information and pick the correct account before calling.
  4. If you administer OneDev, rename duplicate full names so full-name lookup is unambiguous.

Example fix

// before
GET /~ai/get-login-name?userName=John%20Smith   // ambiguous
// after
GET /~ai/get-login-name?userName=john.smith2    // unique login name
Defensive patterns

Strategy: validation

Validate before calling

// resolve uniqueness before calling: use admin user search
const matches = await adminApi.searchUsers(userName); if (matches.length !== 1) throw new Error('userName is ambiguous: ' + userName);

Try / catch

try { return await api.getLoginName(userName); } catch (e) { if (/Multiple users found/i.test(e.message)) { const pick = await promptUserToDisambiguate(userName); return api.getLoginName(pick); } throw e; }

Prevention

When it happens

Trigger: GET /get-login-name?userName=<fullName> where the name is not a unique login name, and several users share that full name, producing matchingUsers.size() > 1.

Common situations: Passing a display name like "John Smith" when two John Smiths exist; passing a non-login name that the service resolves via findByFullName; AI agents guessing user identifiers from conversation text.

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 theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/d39e5644fe920ccf. Report an issue: GitHub.