{"record":{"id":"ba778d80c01f3240","repo":"langgenius/dify","slug":"email-already-in-use","errorCode":"email_already_in_use","errorMessage":"A user with this email already exists.","messagePattern":"A user with this email already exists\\.","errorType":"error_code","errorClass":"EmailAlreadyInUseError","httpStatus":400,"severity":"error","filePath":"api/controllers/console/auth/email_register.py","lineNumber":185,"sourceCode":"\n        # Validate token and get register data\n        register_data = AccountService.get_email_register_data(req_data.token)\n        if not register_data:\n            raise InvalidTokenError()\n        # Must use token in reset phase\n        if register_data.get(\"phase\", \"\") != \"register\":\n            raise InvalidTokenError()\n\n        # Revoke token to prevent reuse\n        AccountService.revoke_email_register_token(req_data.token)\n\n        email = register_data.get(\"email\", \"\")\n        normalized_email = email.lower()\n\n        account = AccountService.get_account_by_email_with_case_fallback(email, session=db.session())\n\n        if account:\n            raise EmailAlreadyInUseError()\n\n        account = self._create_new_account(\n            email=normalized_email,\n            password=req_data.password_confirm,\n            timezone=req_data.timezone,\n            language=req_data.language,\n        )\n        token_pair = AccountService.login(account=account, session=db.session(), ip_address=extract_remote_ip(request))\n        AccountService.reset_login_error_rate_limit(normalized_email)\n\n        return {\"result\": \"success\", \"data\": token_pair.model_dump()}\n\n    def _create_new_account(\n        self,\n        email: str,\n        password: str,\n        timezone: str | None = None,\n        language: str | None = None,","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/auth/email_register.py#L167-L203","documentation":"Raised by EmailAlreadyInUseError in EmailRegisterResetApi.post after the token is validated and revoked, when AccountService.get_account_by_email_with_case_fallback finds an existing account for that email. The case-insensitive lookup means differing capitalization does not bypass it. The token has already been revoked at this point, so the flow cannot be retried with the same token.","triggerScenarios":"POST /console/api/email-register where an account already exists for the email (case-insensitive). The user completed verification but the email was registered by someone else (or themselves in another session) in the meantime.","commonSituations":"Two browser tabs both registering; user forgot they already have an account; race between concurrent registrations; email alias that case-folds onto an existing account; previous failed registration that actually created the account.","solutions":["If the user owns the account, direct them to login or forgot-password instead of registration.","Restart email-send only if the email genuinely should be new; otherwise the account exists.","Add a pre-check (e.g., an existence probe) before starting registration to fail fast.","Handle the 'email_already_in_use' code in the UI with a link to the login flow."],"exampleFix":"// before\nregister({ token, ... }); // user already has account\n// after\nif (res.code === 'email_already_in_use') {\n  router.push('/signin?email=' + encodeURIComponent(email));\n}","handlingStrategy":"try-catch","validationCode":"// Optional pre-check if an existence probe exists; otherwise rely on try-catch\nif (await accountExists(email)) {\n  redirect('/signin?email=' + encodeURIComponent(email));\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await register({ token, ... });\n} catch (e) {\n  if (e.code === 'email_already_in_use') redirect('/signin');\n  else throw e;\n}","preventionTips":["Offer a 'sign in instead' link when registration detects an existing account.","Avoid concurrent registration tabs for the same email.","Remember prior successful registrations to short-circuit."],"tags":["auth","registration","duplicate","email","race-condition"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}