{"record":{"id":"c14c0befcc739e5d","repo":"passbolt/passbolt_api","slug":"please-provide-a-valid-email-address","errorCode":null,"errorMessage":"Please provide a valid email address.","messagePattern":"Please provide a valid email address\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Service/Users/UserRecoverService.php","lineNumber":157,"sourceCode":"        if (!in_array($case, self::ACCOUNT_RECOVERY_CASES)) {\n            throw new BadRequestException(__('Account recovery reason not supported.'));\n        }\n\n        return $case;\n    }\n\n    /**\n     * Assert some username data is provided\n     *\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if the username is not valid\n     * @throws \\Cake\\Http\\Exception\\BadRequestException if the username is not provided\n     * @return string validated username\n     */\n    protected function assertUsername(): string\n    {\n        $username = $this->request->getData('username') ?? null;\n        if (!isset($username) || !is_string($username) || !EmailValidationRule::check($username)) {\n            throw new BadRequestException(__('Please provide a valid email address.'));\n        }\n\n        $user = $this->Users->newEntity([\n            'username' => $username,\n        ], [\n            'validate' => 'recover',\n            'accessibleFields' => [\n                'username' => true,\n            ],\n        ]);\n\n        if ($user->getErrors()) {\n            throw new BadRequestException(__('Please provide a valid email address.'));\n        }\n\n        return $username;\n    }\n","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/Users/UserRecoverService.php#L139-L175","documentation":"Thrown by UserRecoverService::assertUsername when the 'username' request field is missing, is not a string, or fails EmailValidationRule::check — i.e. it is not a syntactically valid email address. This is the first-line format check before the 'recover' validation rules are applied via a Users entity.","triggerScenarios":"POST /recover.json with body missing 'username', with username as a non-string (null, number, object), or with a value that fails email syntax (e.g. \"not-an-email\", \"a@b\", \"@x.com\").","commonSituations":"Scripts interpolating an empty/undefined variable into the JSON body; internationalized or unusual-but-legal emails rejected by the strict rule; form field mis-mapping sending the name under a different key so username arrives null; automation that strips quotes making the email a non-string.","solutions":["Include 'username' as a quoted string in the JSON body and ensure it is a valid email (local@domain.tld).","Validate the email format client-side before calling the endpoint.","Check your client code for undefined/empty variables being serialized.","If the email is valid but still rejected, compare it against CakePHP's EmailValidationRule behavior (special characters, IDN) and try the canonical form."],"exampleFix":"// before\ncurl -d '{\"username\":\"\"}' /recover.json  // 400\n\n// after\ncurl -d '{\"username\":\"user@example.com\"}' /recover.json","handlingStrategy":"validation","validationCode":"const EMAIL_RE = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nif (typeof username !== 'string' || !EMAIL_RE.test(username)) {\n  throw new TypeError('username must be a valid email address');\n}","typeGuard":"const isEmail = (v) => typeof v === 'string' && /^\\S+@\\S+\\.\\S+$/.test(v);","tryCatchPattern":"try {\n  await recover({ username });\n} catch (e) {\n  if (e.response?.body?.message?.includes('valid email address')) {\n    showFieldError('username', 'Enter a valid email address');\n  }\n}","preventionTips":["Validate email format client-side before calling /recover.","Ensure the username key is always present and string-typed in the request body.","Watch for empty/undefined variables silently serialized into JSON payloads.","Note that extremely unusual emails may pass basic regex but fail server rules — keep both layers consistent."],"tags":["passbolt","account-recovery","bad-request","email-validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}