passbolt/passbolt_api · error · BadRequestException
Please provide a valid email address.
Error message
Please provide a valid email address.
What it means
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.
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.
Example fix
// before
curl -d '{"username":""}' /recover.json // 400
// after
curl -d '{"username":"user@example.com"}' /recover.json Defensive patterns
Strategy: validation
Validate before calling
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (typeof username !== 'string' || !EMAIL_RE.test(username)) {
throw new TypeError('username must be a valid email address');
} Type guard
const isEmail = (v) => typeof v === 'string' && /^\S+@\S+\.\S+$/.test(v);
Try / catch
try {
await recover({ username });
} catch (e) {
if (e.response?.body?.message?.includes('valid email address')) {
showFieldError('username', 'Enter a valid email address');
}
} Prevention
- 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.
When it happens
Trigger: 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").
Common situations: 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.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Account recovery case must be a string.
- Account recovery reason not supported.
- Account recovery is disabled.
- An array of arrays is expected.
- An authentication token should be provided.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/c14c0befcc739e5d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Service/Users/UserRecoverService.php:157
if (!in_array($case, self::ACCOUNT_RECOVERY_CASES)) {
throw new BadRequestException(__('Account recovery reason not supported.'));
}
return $case;
}
/**
* Assert some username data is provided
*
* @throws \Cake\Http\Exception\BadRequestException if the username is not valid
* @throws \Cake\Http\Exception\BadRequestException if the username is not provided
* @return string validated username
*/
protected function assertUsername(): string
{
$username = $this->request->getData('username') ?? null;
if (!isset($username) || !is_string($username) || !EmailValidationRule::check($username)) {
throw new BadRequestException(__('Please provide a valid email address.'));
}
$user = $this->Users->newEntity([
'username' => $username,
], [
'validate' => 'recover',
'accessibleFields' => [
'username' => true,
],
]);
if ($user->getErrors()) {
throw new BadRequestException(__('Please provide a valid email address.'));
}
return $username;
}
View on GitHub (pinned to 31c1bbc10f)