makeplane/plane · warning · AuthenticationException

5095

5095

Error message

EXPIRED_MAGIC_CODE_SIGN_IN

What it means

Raised in MagicCodeProvider.set_user_data (magic_code.py:201) in the else-branch where the Redis key self.key does NOT exist (token missing or expired) AND a User exists for the cleaned email. Code 5095, payload {email}. This means no valid token to verify against — the code was never issued, already used, or expired.

Source

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

                        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)},
                )
            else:
                raise AuthenticationException(
                    error_code=AUTHENTICATION_ERROR_CODES["EXPIRED_MAGIC_CODE_SIGN_UP"],
                    error_message="EXPIRED_MAGIC_CODE_SIGN_UP",
                    payload={"email": str(email)},
                )

View on GitHub (pinned to 1c8a60f858)

Solutions

  1. Request a fresh magic code and verify within the 600s TTL.
  2. Ensure only the newest code is used (requesting a new code invalidates the prior token context for that key).
  3. If persistent, check Redis connectivity and that the magic_* keys are not being evicted (maxmemory policy).

Example fix

// before: verify after 600s, key expired, user exists -> 5095
// after: regenerate code, verify immediately
Defensive patterns

Strategy: validation

Validate before calling

from plane.settings.redis import redis_instance

def token_still_valid(token_key: str) -> bool:
    ri = redis_instance()
    return bool(ri.exists(token_key)) and (ri.ttl(token_key) > 0)

Try / catch

try:
    provider.set_user_data()
except AuthenticationException as e:
    if e.error_code == 5095:
        provider.initiate()  # issue a fresh code for the existing user
    else:
        raise

Prevention

When it happens

Trigger: Calling verify when ri.exists(self.key) is False: the 600s TTL elapsed, the token was consumed by a successful login, invalidated by exhaustion, or Redis was flushed. If the email maps to an existing User, AuthenticationException code 5095 is raised.

Common situations: User waits too long (>600s) before entering the code; user already used the code and clicks verify again; Redis restart/flush dropped the key; user is verifying against a code from an old email after requesting a new one (which reused/overwrote the key).

Related errors


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