langgenius/dify · error · EmailCodeError
email_code_error
email_code_error
Error message
Email code is invalid or expired.
What it means
Raised by EmailCodeError in EmailRegisterCheckApi.post when req_data.code does not equal the code stored in the registration token. Each failure increments the error-rate-limit counter via add_email_register_error_rate_limit, eventually producing error 401. The code is a short numeric/alphanumeric pin delivered by email.
Source
Thrown at api/controllers/console/auth/email_register.py:140
user_email = req_data.email.lower()
is_email_register_error_rate_limit = AccountService.is_email_register_error_rate_limit(user_email)
if is_email_register_error_rate_limit:
raise EmailRegisterLimitError()
token_data = AccountService.get_email_register_data(req_data.token)
if token_data is None:
raise InvalidTokenError()
token_email = token_data.get("email")
normalized_token_email = token_email.lower() if isinstance(token_email, str) else token_email
if user_email != normalized_token_email:
raise InvalidEmailError()
if req_data.code != token_data.get("code"):
AccountService.add_email_register_error_rate_limit(user_email)
raise EmailCodeError()
# Verified, revoke the first token
AccountService.revoke_email_register_token(req_data.token)
# Refresh token data by generating a new token
_, new_token = AccountService.generate_email_register_token(
user_email, code=req_data.code, additional_data={"phase": "register"}
)
AccountService.reset_email_register_error_rate_limit(user_email)
return {"is_valid": True, "email": normalized_token_email, "token": new_token}
@console_ns.route("/email-register")
class EmailRegisterResetApi(Resource):
@setup_required
@email_password_login_enabled
@email_register_enabledView on GitHub (pinned to ef8544b173)
Solutions
- Trim whitespace and re-enter the code from the most recent registration email.
- If unsure, request a new code via email-send and use the new token+code pair together.
- Track attempts client-side and warn the user before they hit the rate-limit threshold.
- Verify the code input has no thousands separators or formatting inserted by autofill.
Example fix
// before
checkValidity({ email, token, code: rawInput });
// after: normalize and pair with the latest token
checkValidity({ email, token: latestToken, code: rawInput.trim() }); Defensive patterns
Strategy: validation
Validate before calling
const cleanCode = String(code).trim();
if (!/^\d{4,8}$/.test(cleanCode)) {
warnInvalidCodeFormat();
return;
} Type guard
function looksLikeVerificationCode(c) { return typeof c === 'string' && /^\d{4,8}$/.test(c.trim()); } Try / catch
try {
await checkValidity({ email, token, code: cleanCode });
} catch (e) {
if (e.code === 'email_code_error') bumpAttempts();
else if (e.code === 'email_register_limit') showCooldown();
else throw e;
} Prevention
- Trim and validate code format client-side before sending.
- Use the code from the most recent email only.
- Disable autofill on the code input.
When it happens
Trigger: POST /console/api/email-register/validity with a wrong, expired, already-consumed, or typo'd verification code while the token and email are valid.
Common situations: User mistypes the 6-digit code; code from a previous email is used after a resend; OCR misreads the code; user pastes with leading/trailing whitespace.
Related errors
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/52a4ade4ef737bfc.
Report an issue: GitHub.