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
- Pass the exact unique login name instead of a full name.
- List users (via admin user query) to find the unique login name and use that.
- Include more disambiguating information and pick the correct account before calling.
- 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
- Always pass unique login names, never display names
- Keep full names unique in the OneDev user directory
- Surface ambiguity to the end user instead of guessing
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
- User not found: ${userName}
- Unauthenticated
- Count should not be greater than ${RestConstants.MAX_PAGE_SI
- No permission to access issue: ${referenceString}
- Issue not found: ${referenceString}
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/d39e5644fe920ccf.
Report an issue: GitHub.