infiniflow/ragflow · error · AdminException

Invalid email address: {username}!

Error message

Invalid email address: {username}!

What it means

Raised by UserMgr.create_user (admin/server/services.py:85) as an AdminException (HTTP 400) when the supplied username fails the email regex ^[\w\._-]+@([\w_-]+\.)+[\w-]{2,}$. The admin user-management API only accepts users identified by email address, so a malformed address is rejected before any database lookup. The message embeds the offending username verbatim.

Source

Thrown at admin/server/services.py:85

                    "email": user.email,
                    "language": user.language,
                    "last_login_time": user.last_login_time,
                    "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:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Pass a well-formed email address as username, e.g. 'user@example.com' (needs a dotted domain of 2+ letters).
  2. Strip/trim whitespace from the username before calling create_user.
  3. If you need '+' addressing, pre-validate and normalize the address (e.g. strip the +tag part) or relax the regex in services.py to accept it.
  4. Add client-side email format validation before invoking the admin API so users get feedback early.

Example fix

# before
UserMgr.create_user('user+tag@example.com', encrypted_pw)  # raises Invalid email address

# after
import re
email = 'user+tag@example.com'.strip()
assert re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,}$", email), 'address rejected by admin API'
UserMgr.create_user(email.split('+')[0] + '@example.com', encrypted_pw)
Defensive patterns

Strategy: validation

Validate before calling

import re

EMAIL_RE = re.compile(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,}$")

def is_valid_admin_email(username: str) -> bool:
    return bool(username and EMAIL_RE.match(username.strip()))

Type guard

def is_valid_admin_email(username: str) -> bool:
    import re
    return isinstance(username, str) and bool(re.match(r"^[\w\._-]+@([\w_-]+\.)+[\w-]{2,}$", username.strip()))

Try / catch

from admin.server.exceptions import AdminException
try:
    UserMgr.create_user(email, encrypted_pw, role)
except AdminException as e:
    if e.code == 400 and e.message.startswith('Invalid email address'):
        raise ValueError(f'bad email input: {email!r}') from e
    raise

Prevention

When it happens

Trigger: POST to the admin CLI/server 'create user' endpoint with a non-email username: missing '@', no dot in the domain, a single-label domain ('user@localhost'), or characters outside [A-Za-z0-9_.-] such as 'user+tag@example.com' (the '+' is rejected by this regex).

Common situations: Scripts that pass a nickname or phone-style id instead of an email; plus-addressed addresses; IDN/unicode emails; leading/trailing whitespace in shell arguments; typos in automation config files feeding the admin command.

Related errors


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