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_enabled

View on GitHub (pinned to ef8544b173)

Solutions

  1. Trim whitespace and re-enter the code from the most recent registration email.
  2. If unsure, request a new code via email-send and use the new token+code pair together.
  3. Track attempts client-side and warn the user before they hit the rate-limit threshold.
  4. 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

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.