{"record":{"id":"dc5927d4f5731fc5","repo":"makeplane/plane","slug":"5005","errorCode":"5005","errorMessage":"INVALID_EMAIL","messagePattern":"INVALID_EMAIL","errorType":"exception","errorClass":"AuthenticationException","httpStatus":null,"severity":"error","filePath":"apps/api/plane/authentication/adapter/base.py","lineNumber":68,"sourceCode":"        raise NotImplementedError\n\n    def set_token_data(self, data):\n        self.token_data = data\n\n    def set_user_data(self, data):\n        self.user_data = data\n\n    def create_update_account(self, user):\n        raise NotImplementedError\n\n    def authenticate(self):\n        raise NotImplementedError\n\n    def sanitize_email(self, email):\n        # Check if email is present\n        if not email:\n            self.logger.error(\"Email is not present\")\n            raise AuthenticationException(\n                error_code=AUTHENTICATION_ERROR_CODES[\"INVALID_EMAIL\"],\n                error_message=\"INVALID_EMAIL\",\n                payload={\"email\": email},\n            )\n\n        # Sanitize email\n        email = str(email).lower().strip()\n\n        # validate email\n        try:\n            validate_email(email)\n        except ValidationError:\n            self.logger.warning(\"Email is not valid\")\n            raise AuthenticationException(\n                error_code=AUTHENTICATION_ERROR_CODES[\"INVALID_EMAIL\"],\n                error_message=\"INVALID_EMAIL\",\n                payload={\"email\": email},\n            )","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/makeplane/plane/blob/1c8a60f858d8472aa56e29994ec1c7926da2c6ce/apps/api/plane/authentication/adapter/base.py#L50-L86","documentation":"In the authentication adapter's sanitize_email, the first check is that an email value is truthy. If email is None, empty string, or otherwise falsy, AuthenticationException is raised with error_code 5005 (INVALID_EMAIL) and the raw email in the payload. This is the 'missing email' branch, distinct from the 'malformed email' branch at line 82.","triggerScenarios":"Sign-up/sign-in request where the email field is omitted or empty; JSON body missing the email key; form data where email input is blank.","commonSituations":"Client bug sending { password: '...' } with no email; middleware stripping empty fields; mobile client not binding the email input.","solutions":["Ensure the client always sends a non-empty email field for auth endpoints.","Add required-field validation on the request serializer before reaching the adapter.","Surface error_code 5005 to the user as 'Email is required'."],"exampleFix":"# before\nadapter.sanitize_email(payload.get('email'))\n\n# after\nemail = (payload.get('email') or '').strip()\nif not email:\n    raise ValidationError({'email': 'This field is required.'})\nadapter.sanitize_email(email)","handlingStrategy":"validation","validationCode":"email = (payload.get('email') or '').strip()\nif not email:\n    raise ValidationError({'email': 'required'})","typeGuard":"def is_present_email(v): return isinstance(v, str) and v.strip() != ''","tryCatchPattern":"try:\n    adapter.sanitize_email(payload.get('email'))\nexcept AuthenticationException as e:\n    if e.error_code == 5005 and not payload.get('email'):\n        return bad_request('Email is required')\n    raise","preventionTips":["Validate required email at the serializer boundary","Send non-empty email from clients","Map code 5005 to 'Email required' in the UI"],"tags":["auth","email","validation","authentication-adapter"],"backgroundTag":null,"analyzedSha":"1c8a60f858d8472aa56e29994ec1c7926da2c6ce","analyzedAt":"2026-08-12T14:44:31.636Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}