infiniflow/ragflow · error · UserNotFoundError
User '{username}' not found
Error message
User '{username}' not found What it means
UserNotFoundError raised inside the check_admin_auth decorator (admin/server/auth.py:141) when flask-login's current_user.id no longer resolves to a row via UserService.filter_by_id. The request presented a structurally valid JWT/access token (load_user succeeded) but the user behind that UUID has since been deleted from the database. Note the message uses '{username}' although the lookup is by id.
Source
Thrown at admin/server/auth.py:141
"parser_ids": settings.PARSERS,
"img2txt_id": settings.VISION_MDL,
"rerank_id": settings.RERANK_MDL,
}
usr_tenant = {"tenant_id": user_info["id"], "user_id": user_info["id"], "invited_by": user_info["id"], "role": role}
# tenant_llm = get_init_tenant_llm(user_info["id"])
TenantService.insert(**tenant)
UserTenantService.insert(**usr_tenant)
# TenantLLMService.insert_many(tenant_llm)
logging.info(f"Added tenant for email: {user_info['email']}, A default tenant has been set; changing the default models after login is strongly recommended.")
def check_admin_auth(func):
@wraps(func)
def wrapper(*args, **kwargs):
user = UserService.filter_by_id(current_user.id)
if not user:
raise UserNotFoundError(current_user.email)
if not user.is_superuser:
raise AdminException("Not admin", 403)
if user.is_active == ActiveEnum.INACTIVE.value:
raise AdminException(f"User {current_user.email} inactive", 403)
return func(*args, **kwargs)
return wrapper
def login_admin(email: str, password: str):
"""
:param email: admin email
:param password: string before decrypt (RSA encrypted + base64 encoded)
"""
users = UserService.query(email=email)
if not users:
raise UserNotFoundError(email)View on GitHub (pinned to 554fb1133a)
Solutions
- Re-login to obtain a fresh token for an existing admin account.
- If the user should still exist, restore its row in the user table (the id is embedded in the token's UUID).
- On the server, treat UserNotFoundError as 401 so clients know to re-authenticate rather than retry the same token.
Defensive patterns
Strategy: try-catch
Validate before calling
from api.db.services import UserService
user = UserService.filter_by_id(user_id_from_token)
if not user:
# token points at a deleted account: refresh credentials before calling admin APIs
relogin() Type guard
def token_user_exists(user_id: str) -> bool:
return UserService.filter_by_id(user_id) is not None Try / catch
from api.common.exceptions import UserNotFoundError
try:
admin_client.users.list()
except UserNotFoundError:
# stored token references a deleted user; drop it and re-authenticate
admin_client.logout(); token = fresh_login() Prevention
- Re-login on 401-class errors instead of retrying with the same token.
- When deleting users, revoke/invalidate their stored tokens in automation configs.
- Prefer short-lived tokens in scripts so deletions self-heal at next login.
When it happens
Trigger: Any @check_admin_auth-decorated admin endpoint called with a token belonging to a deleted user: admin deleted the account (or DB was pruned) while the client kept using a previously issued access_token (get_uuid() stored on login, wrapped in a JWT that may still decode).
Common situations: Long-lived tokens in scripts/CLIs after the user row was removed; restoring a DB dump that lacks the user whose token a CI job holds; deleting a test admin account without revoking its tokens.
Related errors
- Email and password do not match!
- User {email} inactive
- main() must be defined or exported.
- Failed to delete memory
- Failed to update memory
AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15).
Data as JSON: /api/errors/098a346476b78db1.
Report an issue: GitHub.