{"record":{"id":"d3ae263a685972dc","repo":"infiniflow/ragflow","slug":"login-failed-res-get-message","errorCode":null,"errorMessage":"Login failed: {res.get('message')}","messagePattern":"Login failed: (.+?)","errorType":"exception","errorClass":"AuthException","httpStatus":401,"severity":"error","filePath":"admin/client/user.py","lineNumber":72,"sourceCode":"    msg = res.get(\"message\", \"\")\n    if \"has already registered\" in msg:\n        return\n    raise AuthException(f\"Register failed: {msg}\")\n\n\ndef login_user(client: HttpClient, server_type: str, email: str, password: str) -> str:\n    password_enc = encrypt_password(password)\n    payload = {\"email\": email, \"password\": password_enc}\n    if server_type == \"admin\":\n        response = client.request(\"POST\", \"/admin/login\", use_api_base=True, auth_kind=None, json_body=payload)\n    else:\n        response = client.request(\"POST\", \"/auth/login\", use_api_base=True, auth_kind=None, json_body=payload)\n    try:\n        res = response.json()\n    except Exception as exc:\n        raise AuthException(f\"Login failed: invalid JSON response ({exc})\") from exc\n    if res.get(\"code\") != 0:\n        raise AuthException(f\"Login failed: {res.get('message')}\")\n    token = response.headers.get(\"Authorization\")\n    if not token:\n        raise AuthException(\"Login failed: missing Authorization header\")\n    return token\n","sourceCodeStart":54,"sourceCodeEnd":77,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/admin/client/user.py#L54-L77","documentation":"Raised by login_user when the login endpoint returned valid JSON but with code != 0 — the server explicitly rejected the login. The server's message is embedded (e.g. wrong email/password, account locked, captcha required). This is the standard credential-authentication failure path for both admin (/admin/login) and user (/auth/login) server types.","triggerScenarios":"POST email+encrypted password to /admin/login or /auth/login where the account does not exist, the password is wrong (note passwords are passed through encrypt_password — a mismatched encoding scheme also produces 'wrong password'), or the account is disabled/locked.","commonSituations":"Password encrypted differently than the server expects (encryption scheme drift between client and server versions); account registered with a different email; admin login attempted against a user-only endpoint or vice versa; account deactivated.","solutions":["Read the embedded server message — it distinguishes wrong password vs. nonexistent user vs. locked account","Verify encrypt_password matches the server's expected encoding (same base64/MD5 scheme and salt)","Confirm using the right server_type/endpoint: 'admin' goes to /admin/login, otherwise /auth/login","If the user was just registered, confirm registration succeeded (error 57 would have fired otherwise)"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"# verify the password encoding matches what the server expects before login\nfrom admin.client.user import encrypt_password\n\nassert encrypt_password(\"test-password\") != \"\", \"encrypt_password produced empty output\"\nassert \"@\" in email, \"email looks malformed\"","typeGuard":"def is_rejected_login(res: dict) -> bool:\n    \"\"\"Server returned JSON envelope with a rejection code.\"\"\"\n    return isinstance(res, dict) and res.get(\"code\") != 0","tryCatchPattern":"try:\n    token = login_user(client, server_type, email, password)\nexcept AuthException as e:\n    msg = str(e)\n    if \"password\" in msg.lower() or \"email\" in msg.lower():\n        # credential problem — do not retry with the same values\n        raise SystemExit(f\"Check credentials: {msg}\")\n    if \"locked\" in msg.lower() or \"disabled\" in msg.lower():\n        raise SystemExit(f\"Account issue: {msg}\")\n    raise","preventionTips":["Confirm encrypt_password matches the server's expected encoding (scheme drift causes wrong-password errors)","Use the correct server_type so the request hits /admin/login vs /auth/login","Register the user first and assert registration succeeded before attempting login"],"tags":["auth","login","credentials","python","api"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}