passbolt/passbolt_api · error · Cake\Http\Exception\InternalErrorException
Invalid UserControl username.
Error message
Invalid UserControl username.
What it means
UserAccessControl::__construct() validates its optional $username argument with EmailValidationRule::check(). If a username is supplied that is not a valid email address, it throws InternalErrorException('Invalid UserControl username.'), because the UAC username is always expected to be the user's email.
Solutions
- Validate the email before constructing the object (EmailValidationRule::check) and return a client error for bad input.
- Pass null instead of an empty string when the username is unknown — only set it when it is a valid email.
- Ensure the value passed is the user's email address, not a display name or login handle.
Example fix
// before
$uac = new UserAccessControl($role, $userId, $postData['username']); // 500 if not email
// after
$username = $postData['username'] ?? null;
if ($username !== null && !EmailValidationRule::check($username)) {
throw new BadRequestException('Invalid username.');
}
$uac = new UserAccessControl($role, $userId, $username); Defensive patterns
Strategy: validation
Validate before calling
if ($username !== null && !EmailValidationRule::check($username)) {
throw new BadRequestException('A valid email address is required.');
}
$uac = new UserAccessControl($roleName, $userId, $username); Type guard
function isValidUsername(?string $username): bool {
return $username === null || EmailValidationRule::check($username);
} Try / catch
try {
$uac = new UserAccessControl($roleName, $userId, $username);
} catch (\Cake\Http\Exception\InternalErrorException $e) {
if (str_contains($e->getMessage(), 'Invalid UserControl username')) {
throw new BadRequestException('Invalid username supplied.');
}
throw $e;
} Prevention
- Pass null (not '') when the username is unknown so validation is skipped.
- Only pass the user's email field into UserAccessControl, never display names or handles.
- Validate emails at the request boundary with the same EmailValidationRule.
When it happens
Trigger: Constructing `new UserAccessControl($roleName, $userId, $username)` where $username fails email validation — e.g. passing a username/login string that is not an email, an empty-string instead of null, or user-supplied input without validation.
Common situations: Passing request data (username field) directly into UserAccessControl; tests using placeholder names like 'ada' or 'test'; legacy accounts with malformed emails in the database being passed through.
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
- Invalid UserControl user id.
- No email with type "work" was found in the
- The email is already registered.
- group(s) returned by your directory are invalid and will be…
- " " is not a valid contain value.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/bc57dc98cbe7cd5e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Utility/UserAccessControl.php:63
/**
* @var string|null
*/
private ?string $username = null;
/**
* UserAccessControl constructor.
*
* @param string $roleName The role name
* @param string|null $userId the user uuid
* @param string|null $username the user email
*/
public function __construct(string $roleName, ?string $userId = null, ?string $username = null)
{
if (isset($userId) && !Validation::uuid($userId)) {
throw new InternalErrorException('Invalid UserControl user id.');
}
if (isset($username) && !EmailValidationRule::check($username)) {
throw new InternalErrorException('Invalid UserControl username.');
}
$this->userId = $userId;
$this->roleName = $roleName;
$this->username = $username;
}
/**
* Get the user id
*
* @return string|null
*/
public function getId(): ?string
{
return $this->userId;
}
/**
* Get the user role nameView on GitHub (pinned to 31c1bbc10f)