makeplane/plane · warning · AuthenticationException

5090

5090

Error message

INVALID_MAGIC_CODE_SIGN_IN

What it means

Raised in MagicCodeProvider.set_user_data (magic_code.py:187) on the verify path when the submitted code is wrong, the verify budget is NOT yet exhausted, AND the email belongs to an existing User. Code 5090, payload {email}. This is the non-terminal wrong-code error (the user still has attempts remaining).

Source

Thrown at apps/api/plane/authentication/provider/credentials/magic_code.py:187

                if verify_attempts >= self.MAX_VERIFY_ATTEMPTS:
                    # Invalidate the token (and counter) so further attempts
                    # must regenerate; regeneration is itself attempt-counted.
                    ri.delete(self.key)
                    ri.delete(self._verify_attempts_key(self.key))
                    if user_exists:
                        raise AuthenticationException(
                            error_code=AUTHENTICATION_ERROR_CODES["EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN"],
                            error_message="EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN",
                            payload={"email": str(email)},
                        )
                    raise AuthenticationException(
                        error_code=AUTHENTICATION_ERROR_CODES["EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP"],
                        error_message="EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP",
                        payload={"email": str(email)},
                    )

                if user_exists:
                    raise AuthenticationException(
                        error_code=AUTHENTICATION_ERROR_CODES["INVALID_MAGIC_CODE_SIGN_IN"],
                        error_message="INVALID_MAGIC_CODE_SIGN_IN",
                        payload={"email": str(email)},
                    )
                else:
                    raise AuthenticationException(
                        error_code=AUTHENTICATION_ERROR_CODES["INVALID_MAGIC_CODE_SIGN_UP"],
                        error_message="INVALID_MAGIC_CODE_SIGN_UP",
                        payload={"email": str(email)},
                    )
        else:
            email = str(self.key).replace("magic_", "", 1)
            if User.objects.filter(email=email).exists():
                raise AuthenticationException(
                    error_code=AUTHENTICATION_ERROR_CODES["EXPIRED_MAGIC_CODE_SIGN_IN"],
                    error_message="EXPIRED_MAGIC_CODE_SIGN_IN",
                    payload={"email": str(email)},
                )

View on GitHub (pinned to 1c8a60f858)

Solutions

  1. Re-enter the code carefully from the most recent email.
  2. If unsure, wait and re-read the latest magic-code email (older emails' codes are invalid once a new token is issued).
  3. Track remaining attempts client-side; regenerate before hitting MAX_VERIFY_ATTEMPTS to avoid lockout (5100).

Example fix

// before: wrong 6-digit code, user exists -> 5090 (token still valid)
// after: submit the exact 6 digits from the newest email
Defensive patterns

Strategy: try-catch

Validate before calling

from plane.authentication.provider.credentials.magic_code import MagicCodeProvider
from plane.settings.redis import redis_instance

def verify_budget_remaining(token_key: str) -> int:
    ri = redis_instance()
    raw = ri.get(MagicCodeProvider._verify_attempts_key(token_key))
    used = int(raw) if raw else 0
    return max(MagicCodeProvider.MAX_VERIFY_ATTEMPTS - used, 0)

Try / catch

try:
    provider.set_user_data()
except AuthenticationException as e:
    if e.error_code == 5090:
        show_remaining_attempts_and_re_prompt(email=e.payload.get('email'))
    else:
        raise

Prevention

When it happens

Trigger: A valid token exists in Redis (key self.key) but str(token) != str(self.code). The verify counter is incremented atomically; if under MAX_VERIFY_ATTEMPTS and a User exists, AuthenticationException code 5090 is raised. The token stays valid for further attempts.

Common situations: Typo in the 6-digit code, code read from a delayed/truncated email, autofill of a stale code, or transposed digits.

Related errors


AI-assisted analysis of makeplane/plane@1c8a60f858 (2026-08-12). Data as JSON: /api/errors/de90150c93b7b8d0. Report an issue: GitHub.