{"record":{"id":"bc57dc98cbe7cd5e","repo":"passbolt/passbolt_api","slug":"invalid-usercontrol-username","errorCode":null,"errorMessage":"Invalid UserControl username.","messagePattern":"Invalid UserControl username\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"error","filePath":"src/Utility/UserAccessControl.php","lineNumber":63,"sourceCode":"    /**\n     * @var string|null\n     */\n    private ?string $username = null;\n\n    /**\n     * UserAccessControl constructor.\n     *\n     * @param string $roleName The role name\n     * @param string|null $userId the user uuid\n     * @param string|null $username the user email\n     */\n    public function __construct(string $roleName, ?string $userId = null, ?string $username = null)\n    {\n        if (isset($userId) && !Validation::uuid($userId)) {\n            throw new InternalErrorException('Invalid UserControl user id.');\n        }\n        if (isset($username) && !EmailValidationRule::check($username)) {\n            throw new InternalErrorException('Invalid UserControl username.');\n        }\n        $this->userId = $userId;\n        $this->roleName = $roleName;\n        $this->username = $username;\n    }\n\n    /**\n     * Get the user id\n     *\n     * @return string|null\n     */\n    public function getId(): ?string\n    {\n        return $this->userId;\n    }\n\n    /**\n     * Get the user role name","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Utility/UserAccessControl.php#L45-L81","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n$uac = new UserAccessControl($role, $userId, $postData['username']); // 500 if not email\n// after\n$username = $postData['username'] ?? null;\nif ($username !== null && !EmailValidationRule::check($username)) {\n    throw new BadRequestException('Invalid username.');\n}\n$uac = new UserAccessControl($role, $userId, $username);","handlingStrategy":"validation","validationCode":"if ($username !== null && !EmailValidationRule::check($username)) {\n    throw new BadRequestException('A valid email address is required.');\n}\n$uac = new UserAccessControl($roleName, $userId, $username);","typeGuard":"function isValidUsername(?string $username): bool {\n    return $username === null || EmailValidationRule::check($username);\n}","tryCatchPattern":"try {\n    $uac = new UserAccessControl($roleName, $userId, $username);\n} catch (\\Cake\\Http\\Exception\\InternalErrorException $e) {\n    if (str_contains($e->getMessage(), 'Invalid UserControl username')) {\n        throw new BadRequestException('Invalid username supplied.');\n    }\n    throw $e;\n}","preventionTips":["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."],"tags":["validation","email","access-control"],"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-21T09:17:21.228Z"}