{"record":{"id":"f826da60b37b14e9","repo":"makeplane/plane","slug":"5102","errorCode":"5102","errorMessage":"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP","messagePattern":"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"warning","filePath":"apps/api/plane/authentication/provider/credentials/magic_code.py","lineNumber":98,"sourceCode":"\n        key = \"magic_\" + str(self.key)\n\n        # Check if the key already exists in python\n        if ri.exists(key):\n            data = json.loads(ri.get(key))\n\n            current_attempt = data[\"current_attempt\"] + 1\n\n            if data[\"current_attempt\"] > 2:\n                email = str(self.key).replace(\"magic_\", \"\", 1)\n                if User.objects.filter(email=email).exists():\n                    raise AuthenticationException(\n                        error_code=AUTHENTICATION_ERROR_CODES[\"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN\"],\n                        error_message=\"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN\",\n                        payload={\"email\": str(email)},\n                    )\n                else:\n                    raise AuthenticationException(\n                        error_code=AUTHENTICATION_ERROR_CODES[\"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP\"],\n                        error_message=\"EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP\",\n                        payload={\"email\": self.key},\n                    )\n\n            value = {\n                \"current_attempt\": current_attempt,\n                \"email\": str(self.key),\n                \"token\": token,\n            }\n            expiry = 600\n            ri.set(key, json.dumps(value), ex=expiry)\n        else:\n            value = {\"current_attempt\": 0, \"email\": self.key, \"token\": token}\n            expiry = 600\n\n            ri.set(key, json.dumps(value), ex=expiry)\n        # Reset the verify-attempt counter so each newly issued token starts","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/api/plane/authentication/provider/credentials/magic_code.py#L80-L116","documentation":"Raised in MagicCodeProvider.initiate (magic_code.py:98) — the SIGN_UP counterpart of 51. Same trigger (data['current_attempt'] > 2 on the issue path) but raised when NO User exists for the email, signaling an unregistered email hitting its code-issue limit. Code 5102, payload {email: self.key} (note: uses self.key, not the cleaned email).","triggerScenarios":"Repeated initiate() for an email with no User row, within the 600s Redis TTL, pushes current_attempt past 2; the existence check fails and AuthenticationException code 5102 is raised.","commonSituations":"Someone repeatedly requesting a signup magic code without completing it; a bot enumerating emails; a user who keeps typoing their email and resending.","solutions":["Wait for the 600s TTL to expire so the Redis key clears, then request a fresh code.","Verify the email is spelled correctly before requesting (a typo creates a throwaway unregistered entry).","Admin can delete the 'magic_<email>' Redis key to reset the counter immediately."],"exampleFix":"# before: bot spamming signup codes for unknown emails -> 5102\n# redis-cli DEL magic:user@example.com\n# after: counter reset; a fresh code can be issued","handlingStrategy":"validation","validationCode":"import json\nfrom plane.settings.redis import redis_instance\n\ndef can_issue_magic_code_signup(email: str) -> bool:\n    ri = redis_instance()\n    key = 'magic_' + str(email)\n    if not ri.exists(key):\n        return True\n    return json.loads(ri.get(key)).get('current_attempt', 0) <= 2","typeGuard":null,"tryCatchPattern":"try:\n    provider.initiate()\nexcept AuthenticationException as e:\n    if e.error_code == 5102:\n        tell_user_to_wait_or_verify_email(email=e.payload.get('email'))\n    else:\n        raise","preventionTips":["Validate the email format/existence before requesting signup codes.","Rate-limit signup code requests per IP/email to discourage enumeration."],"tags":["authentication","magic-code","rate-limit","redis","signup"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}