odysseus-dev/odysseus · error · HTTPException
Current password is incorrect
Error message
Current password is incorrect
What it means
Raised as HTTP 400 by POST /change-password when auth_manager.change_password(user, current_password, new_password) returns falsy. The auth manager re-verifies the current password before rotating the hash; a mismatch (or an internal failure to update) yields falsy. This is the 'prove you own the account' step for password rotation.
Source
Thrown at routes/auth_routes.py:210
pass
return result
@router.get("/policy")
async def auth_policy():
"""Return public auth policy constants for the frontend."""
return auth_manager.policy()
@router.post("/change-password")
async def change_password(body: ChangePasswordRequest, request: Request):
user = _get_current_user(request)
if not user:
raise HTTPException(401, "Not authenticated")
if len(body.new_password) < PASSWORD_MIN_LENGTH:
raise HTTPException(400, f"Password must be at least {PASSWORD_MIN_LENGTH} characters")
current_token = request.cookies.get(SESSION_COOKIE)
ok = await asyncio.to_thread(auth_manager.change_password, user, body.current_password, body.new_password)
if not ok:
raise HTTPException(400, "Current password is incorrect")
await asyncio.to_thread(auth_manager.revoke_user_sessions, user, current_token)
return {"ok": True}
# ------------------------------------------------------------------
# Two-factor authentication
# ------------------------------------------------------------------
@router.post("/2fa/setup")
async def totp_setup(request: Request):
"""Generate a TOTP secret and return the QR code URI."""
user = _get_current_user(request)
if not user:
raise HTTPException(401, "Not authenticated")
if auth_manager.totp_enabled(user):
raise HTTPException(400, "2FA is already enabled")
secret = auth_manager.totp_generate_secret(user)
if not secret:
raise HTTPException(500, "Failed to generate secret")View on GitHub (pinned to f9235ebbf1)
Solutions
- Re-enter the current (old) password exactly — beware autofill putting the new password in the wrong field.
- Clear saved credentials for the site in the password manager, then retry.
- If the old password is genuinely forgotten, use the reset flow / admin reset instead of this endpoint.
- If ALL users fail after an upgrade, re-hash stored passwords or restore verify compatibility with the old scheme.
Defensive patterns
Strategy: validation
Validate before calling
// Guard against autofill putting the NEW password in the CURRENT field
if (currentPassword === newPassword) warn('Current and new passwords look identical — check autofill'); Try / catch
catch (e) { if (e.status === 400 && /current password/i.test(e.message)) focusField('current_password'); } Prevention
- Name autofill attributes correctly: autocomplete='current-password' vs 'new-password'.
- Clear stale credentials for the site in the password manager.
- If the old password is unknown, use the reset flow rather than guessing.
When it happens
Trigger: Sending a wrong current_password while authenticated; sending an empty current_password; or a user record whose stored hash can't be verified after a hashing-scheme migration (indistinguishable from wrong password at the route level).
Common situations: Password managers auto-filling the NEW password into the CURRENT field, users forgetting which password is active after a recent change, or post-migration legacy hashes that verify_password can't read.
Related errors
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/af7bd14230193c58.
Report an issue: GitHub.