infiniflow/ragflow · error · UserAlreadyExistsError

User '{username}' already exists

Error message

User '{username}' already exists

What it means

UserAlreadyExistsError (HTTP 409) raised by UserMgr.create_user (admin/server/services.py:88) when UserService.query(email=username) already returns a row. Emails are the unique user key for the admin surface, so duplicate creation is refused before create_new_user runs. Defined in admin/server/exceptions.py:13.

Source

Thrown at admin/server/services.py:88

                    "is_active": user.is_active,
                    "is_anonymous": user.is_anonymous,
                    "login_channel": user.login_channel,
                    "status": user.status,
                    "is_superuser": user.is_superuser,
                    "create_date": user.create_date,
                    "update_date": user.update_date,
                }
            )
        return result

    @staticmethod
    def create_user(username, password, role="user") -> dict:
        # Validate the email address
        if not re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,}$", username):
            raise AdminException(f"Invalid email address: {username}!")
        # 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}!")

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Treat 409 as success for idempotent provisioning: catch UserAlreadyExistsError and continue, or first check UserService.query(email=...) before calling create_user.
  2. Make bootstrap scripts use get-or-create semantics instead of unconditional create.
  3. If the user should be re-created, delete it first with UserMgr.delete_user(username), then create again.
  4. Verify you are pointed at the right environment/database (a stale dev DB often already holds the account).

Example fix

# before
UserMgr.create_user('user@example.com', pw)  # 409 on second run

# after
from api.db.services import UserService
if UserService.query(email='user@example.com'):
    print('user exists, skipping create')
else:
    UserMgr.create_user('user@example.com', pw)
Defensive patterns

Strategy: try-catch

Validate before calling

from api.db.services import UserService

def user_exists(email: str) -> bool:
    return bool(UserService.query(email=email))

Type guard

def is_new_user(email: str) -> bool:
    from api.db.services import UserService
    return UserService.query(email=email) == []

Try / catch

from admin.server.exceptions import UserAlreadyExistsError
try:
    UserMgr.create_user(email, encrypted_pw, role)
except UserAlreadyExistsError:
    pass  # idempotent provisioning: already created

Prevention

When it happens

Trigger: Creating a user whose email already exists in the user table; re-running a provisioning script that is not idempotent; retrying a previous create that actually succeeded but whose response was lost (timeout, network drop).

Common situations: CI/CD pipelines or docker-entrypoint bootstrap scripts that call 'create admin user' on every start; SSO users provisioned earlier via OIDC/OAuth occupying the same email; manual onboarding where an operator re-adds an existing member.

Related errors


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