{"record":{"id":"07f3b923684f95e9","repo":"mem0ai/mem0","slug":"email-is-already-in-use","errorCode":null,"errorMessage":"Email is already in use.","messagePattern":"Email is already in use\\.","errorType":"http","errorClass":"HTTPException","httpStatus":409,"severity":"warning","filePath":"server/routers/auth.py","lineNumber":190,"sourceCode":"@router.patch(\"/me\", response_model=UserResponse)\ndef update_me(\n    body: UpdateProfileRequest,\n    user: User = Depends(require_auth),\n    db: Session = Depends(get_db),\n):\n    # require_auth resolves the user in its own short-lived session, so `user` is\n    # detached from this request's `db`. Load a session-managed copy to mutate.\n    db_user = db.get(User, user.id)\n    if db_user is None:\n        raise HTTPException(status_code=404, detail=\"User not found.\")\n\n    if body.name is not None and body.name.strip():\n        db_user.name = body.name.strip()\n\n    if body.email is not None and body.email != db_user.email:\n        collision = db.scalar(select(User).where(User.email == body.email, User.id != db_user.id))\n        if collision is not None:\n            raise HTTPException(status_code=409, detail=\"Email is already in use.\")\n        db_user.email = body.email\n\n    db.commit()\n    return db_user\n\n\n@router.post(\"/change-password\", response_model=MessageResponse)\ndef change_password(\n    body: ChangePasswordRequest,\n    user: User = Depends(require_auth),\n    db: Session = Depends(get_db),\n):\n    # require_auth resolves the user in its own short-lived session, so `user` is\n    # detached from this request's `db`. Load a session-managed copy to mutate.\n    db_user = db.get(User, user.id)\n    if db_user is None or not verify_password(body.current_password, db_user.password_hash):\n        raise HTTPException(status_code=401, detail=\"Current password is incorrect.\")\n","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/server/routers/auth.py#L172-L208","documentation":"Raised by PATCH /auth/me when the requested new email already belongs to a different account (select User where email = body.email and id != current user). Email is unique across users, so a profile update that would transfer an email owned by another row is rejected with 409 before any commit.","triggerScenarios":"PATCH /auth/me with {\"email\": \"x@y.z\"} where x@y.z is registered to another user; a user trying to change email to one they registered earlier on a second account; case-sensitive lookup matching an existing row (depending on collation, exact-match here).","commonSituations":"User has two accounts and wants to move the primary email to the current one; typo leads to an already-registered address; team SSO where a colleague's email is entered by mistake.","solutions":["Choose a different email address, or first change/release the email on the account that currently owns it","If the user owns both accounts, log into the other account and change its email (or delete that account), then retry","Operators: if this blocks a legitimate merge, rename the other account's email out of the way in the DB before retrying"],"exampleFix":"// before\nawait patch(\"/auth/me\", { email: \"shared@team.com\" }); // 409 if owned by another user\n\n// after\n// free the email on its current owner first, then apply\nawait patch(\"/auth/me\", { email: \"shared@team.com\" }); // succeeds once the other account no longer holds it","handlingStrategy":"validation","validationCode":"// client-side duplicate check (best effort; server remains authoritative)\nconst taken = await fetch(`/auth/users?email=${encodeURIComponent(newEmail)}`).then(r => r.ok);\nif (taken) showEmailInUseError();","typeGuard":null,"tryCatchPattern":"catch (e) {\n  if (e.status === 409 && e.detail === \"Email is already in use.\") {\n    showFieldError(\"email\", \"This email belongs to another account.\");\n    return; // keep form open, do not re-submit unchanged\n  }\n  throw e;\n}","preventionTips":["Validate email format and show a 409 field error inline instead of a generic failure","Disable the submit button while the request is in flight to avoid duplicate submissions","If a user owns two accounts, provide an account-merge or email-swap flow rather than fighting the 409"],"tags":["auth","email","conflict","http-409"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}