infiniflow/ragflow · error · UserNotFoundError

User '{username}' not found

Error message

User '{username}' not found

What it means

UserNotFoundError (HTTP 404) raised by UserMgr.delete_user (admin/server/services.py:104) when UserService.query_user_by_email(username) returns an empty list. Deletion resolves the account solely by email; no match means nothing to delete. Defined in admin/server/exceptions.py:8.

Source

Thrown at admin/server/services.py:104

        # Check if the email address is already used
        if UserService.query(email=username):
            raise UserAlreadyExistsError(username)
        # Construct user info data
        user_info_dict = {
            "email": username,
            "nickname": "",  # ask user to edit it manually in settings.
            "password": decrypt(password),
            "login_channel": "password",
            "is_superuser": role == "admin",
        }
        return create_new_user(user_info_dict)

    @staticmethod
    def delete_user(username):
        # use email to delete
        user_list = UserService.query_user_by_email(username)
        if not user_list:
            raise UserNotFoundError(username)
        if len(user_list) > 1:
            raise AdminException(f"Exist more than 1 user: {username}!")
        usr = user_list[0]
        return delete_user_data(usr.id)

    @staticmethod
    def update_user_password(username, new_password) -> str:
        # use email to find user. check exist and unique.
        user_list = UserService.query_user_by_email(username)
        if not user_list:
            raise UserNotFoundError(username)
        elif len(user_list) > 1:
            raise AdminException(f"Exist more than 1 user: {username}!")
        # check new_password different from old.
        usr = user_list[0]
        psw = decrypt(new_password)
        # SSO-provisioned users (OIDC/OAuth) have no local password (usr.password is None):
        # skip the equality check, which would otherwise crash inside werkzeug's split().

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Verify the email exists first: query with UserService.query_user_by_email(username) or UserMgr.get_user_details(username).
  2. Make teardown idempotent: catch UserNotFoundError and treat it as already-deleted.
  3. Copy the exact email from get_all_users() output rather than typing it.
  4. Confirm you are connected to the intended database/instance.

Example fix

# before
UserMgr.delete_user('user@example.com')  # 404

# after
from admin.server.exceptions import UserNotFoundError
try:
    UserMgr.delete_user('user@example.com')
except UserNotFoundError:
    print('already gone')
Defensive patterns

Strategy: try-catch

Validate before calling

from api.db.services import UserService

def can_delete(email: str) -> bool:
    users = UserService.query_user_by_email(email.strip())
    return len(users) == 1

Try / catch

from admin.server.exceptions import UserNotFoundError
try:
    UserMgr.delete_user(email)
except UserNotFoundError:
    pass  # already gone; idempotent teardown

Prevention

When it happens

Trigger: DELETE admin API call with a typo'd or unknown email; deleting a user already removed; passing a nickname/user-id where an email is required; wrong database/environment so the account does not exist there.

Common situations: Re-running a teardown script after it already succeeded; case-mismatch in the email (lookup is by exact email string); environments drifting between staging and prod; users provisioned under a different email by SSO.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/5a3389d81b1d8315. Report an issue: GitHub.