infiniflow/ragflow · critical · AdminException
More than one user with username '{username}' found!
Error message
More than one user with username '{username}' found! What it means
AdminException (HTTP 400) raised by UserMgr.get_user_api_key (admin/server/services.py:163) with the message "More than one user with username '{username}' found!" when the email matches multiple rows. Since tenant_id is taken from user_list[0].id, an ambiguous match would list the wrong tenant's keys, so it is refused.
Source
Thrown at admin/server/services.py:163
if not target_status:
raise AdminException(f"Invalid activate_status: {activate_status}")
if target_status == usr.is_active:
return f"User activate status is already {_activate_status}!"
# update is_active
update_dict = {"is_active": target_status}
if target_status == ActiveEnum.INACTIVE.value:
update_dict["access_token"] = f"INVALID_{secrets.token_hex(16)}"
UserService.update_user(usr.id, update_dict)
return f"Turn {_activate_status} user activate status successfully!"
@staticmethod
def get_user_api_key(username: str) -> list[dict[str, Any]]:
# use email to find user. check exist and unique.
user_list: list[Any] = UserService.query_user_by_email(username)
if not user_list:
raise UserNotFoundError(username)
elif len(user_list) > 1:
raise AdminException(f"More than one user with username '{username}' found!")
usr: Any = user_list[0]
# tenant_id is typically the same as user_id for the owner tenant
tenant_id: str = usr.id
# Query all API keys for this tenant
api_keys: Any = APITokenService.query(tenant_id=tenant_id)
result: list[dict[str, Any]] = []
for key in api_keys:
result.append(key.to_dict())
return result
@staticmethod
def save_api_key(api_key: dict[str, Any]) -> bool:
return APITokenService.save(**api_key)
View on GitHub (pinned to 554fb1133a)
Solutions
- Enumerate duplicates: SELECT id, email, create_date FROM user WHERE email = '<username>';
- Keep exactly one row (merge or delete extras).
- Add a unique index on email to prevent recurrence.
- Retry the key listing after dedup.
Example fix
-- before SELECT COUNT(*) FROM user WHERE email='user@example.com'; -- >1 -- after: dedupe, constrain, retry DELETE FROM user WHERE email='user@example.com' AND id NOT IN (SELECT * FROM (SELECT MAX(id) FROM user WHERE email='user@example.com') k); ALTER TABLE user ADD UNIQUE KEY uq_user_email (email);
Defensive patterns
Strategy: validation
Validate before calling
from api.db.services import UserService
def assert_unique_target(email: str) -> None:
users = UserService.query_user_by_email(email)
if len(users) != 1:
raise RuntimeError(f'{email}: {len(users)} rows; tenant_id would be ambiguous') Try / catch
from admin.server.exceptions import AdminException
try:
keys = UserMgr.get_user_api_key(email)
except AdminException as e:
if 'More than one user' in e.message:
raise RuntimeError('duplicate users; key listing unsafe until deduped') from e
raise Prevention
- Ensure a unique index on email exists from day one.
- Audit for duplicate emails during upgrades and after data imports.
- Remember tenant_id derives from user id — ambiguous users make every tenant-scoped admin call unsafe.
When it happens
Trigger: Duplicate user rows sharing the same email (data import, missing unique constraint, racing SSO provisioning); every key-listing call for that email then fails.
Common situations: Databases upgraded without adding the email unique index; merged environments; concurrent first-login provisioning via OIDC creating the account twice.
Related errors
- Exist more than 1 user: {username}!
- 400
- Failed to get skill folder ID
- Failed to get version folder ID
- Invalid email address: {username}!
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/9c1a92388033831c.
Report an issue: GitHub.