{"record":{"id":"fdfa514e8cbc02d3","repo":"langgenius/dify","slug":"invalid-email","errorCode":"invalid_email","errorMessage":"The email address is not valid.","messagePattern":"The email address is not valid\\.","errorType":"error_code","errorClass":"InvalidEmailError","httpStatus":400,"severity":"error","filePath":"api/controllers/console/auth/email_register.py","lineNumber":136,"sourceCode":"    @console_ns.response(200, \"Success\", console_ns.models[VerificationTokenResponse.__name__])\n    @model_validate(EmailRegisterValidityPayload)\n    def post(self, req_data: EmailRegisterValidityPayload):\n\n        user_email = req_data.email.lower()\n\n        is_email_register_error_rate_limit = AccountService.is_email_register_error_rate_limit(user_email)\n        if is_email_register_error_rate_limit:\n            raise EmailRegisterLimitError()\n\n        token_data = AccountService.get_email_register_data(req_data.token)\n        if token_data is None:\n            raise InvalidTokenError()\n\n        token_email = token_data.get(\"email\")\n        normalized_token_email = token_email.lower() if isinstance(token_email, str) else token_email\n\n        if user_email != normalized_token_email:\n            raise InvalidEmailError()\n\n        if req_data.code != token_data.get(\"code\"):\n            AccountService.add_email_register_error_rate_limit(user_email)\n            raise EmailCodeError()\n\n        # Verified, revoke the first token\n        AccountService.revoke_email_register_token(req_data.token)\n\n        # Refresh token data by generating a new token\n        _, new_token = AccountService.generate_email_register_token(\n            user_email, code=req_data.code, additional_data={\"phase\": \"register\"}\n        )\n\n        AccountService.reset_email_register_error_rate_limit(user_email)\n        return {\"is_valid\": True, \"email\": normalized_token_email, \"token\": new_token}\n\n\n@console_ns.route(\"/email-register\")","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/auth/email_register.py#L118-L154","documentation":"Raised by InvalidEmailError in EmailRegisterCheckApi.post when the lowercased email in the request body does not match the email bound to the registration token. The token was issued for one address; the client is now claiming a different one. This guards against token/email substitution mid-flow.","triggerScenarios":"POST /console/api/email-register/validity where the token's stored email differs from req_data.email (after both are lowercased). Common when a user starts registration with one address and types another at verification, or when the client passes the wrong email field.","commonSituations":"Plus-addressing differences (user+test@x vs user@x), autocorrect changing the address between steps, shared browser where two users mix up tabs, or a frontend bug sending stale email state.","solutions":["Use the exact email address that received the registration link, character-for-character.","Pull email from the same client state that received the token, not from a re-typed input.","Normalize both sides to lowercase before comparing client-side as a sanity check.","If the wrong email was registered, restart email-send with the correct address."],"exampleFix":"// before\ncheckValidity({ email: typedEmail, token, code });\n// after: derive email from the token-issuing flow\ncheckValidity({ email: issuedToEmail.toLowerCase(), token, code });","handlingStrategy":"validation","validationCode":"// Derive email from the same state that holds the token\nconst emailForCheck = issuedToEmail.toLowerCase();\nif (emailForCheck !== userInputEmail.toLowerCase()) {\n  warnEmailMismatch();\n  return;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await checkValidity({ email: emailForCheck, token, code });\n} catch (e) {\n  if (e.code === 'invalid_email') showEmailMismatchHint();\n  else throw e;\n}","preventionTips":["Freeze the email field once the token is issued, or pre-fill it read-only.","Lowercase both sides before comparing.","Do not let the user retype the email at the verification step."],"tags":["auth","registration","email-mismatch","validation"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}