{"record":{"id":"a054d204b81ca6e0","repo":"passbolt/passbolt_api","slug":"invalid-usercontrol-user-id","errorCode":null,"errorMessage":"Invalid UserControl user id.","messagePattern":"Invalid UserControl user id\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"error","filePath":"src/Utility/UserAccessControl.php","lineNumber":60,"sourceCode":"     */\n    private string $roleName;\n\n    /**\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    }","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Utility/UserAccessControl.php#L42-L78","documentation":"UserAccessControl::__construct() validates its optional $userId argument with Cake's Validation::uuid(). If a userId is provided but is not a valid UUID string, it throws InternalErrorException('Invalid UserControl user id.'), since access-control context must be anchored to a valid user identifier.","triggerScenarios":"Constructing `new UserAccessControl($roleName, $userId)` where $userId is a non-UUID string (e.g. an integer id, garbage, or a concatenated value) — commonly when the id comes from an unvalidated request parameter or a legacy column.","commonSituations":"Passing route/query parameters straight into UserAccessControl without prior UUID validation; tests using fake ids like '1' or 'test'; refactored code passing username where userId was expected.","solutions":["Validate/normalize the id with Validation::uuid($userId) before constructing UserAccessControl, and reject invalid requests earlier (400).","Ensure the value passed really is the user UUID, not a numeric/legacy id — fetch the UUID from the users table if needed.","Return a proper client error instead of surfacing the internal 500: validate input at the controller layer before building the access control object."],"exampleFix":"// before\n$uac = new UserAccessControl($roleName, $this->request->getQuery('user_id')); // 500 if invalid\n// after\n$userId = $this->request->getQuery('user_id');\nif ($userId !== null && !Validation::uuid($userId)) {\n    throw new BadRequestException('Invalid user id.');\n}\n$uac = new UserAccessControl($roleName, $userId);","handlingStrategy":"validation","validationCode":"if ($userId !== null && !\\Cake\\Validation\\Validation::uuid($userId)) {\n    throw new BadRequestException('A valid user id (UUID) is required.');\n}\n$uac = new UserAccessControl($roleName, $userId);","typeGuard":"function isValidUserId(?string $userId): bool {\n    return $userId === null || \\Cake\\Validation\\Validation::uuid($userId);\n}","tryCatchPattern":"try {\n    $uac = new UserAccessControl($roleName, $userId);\n} catch (\\Cake\\Http\\Exception\\InternalErrorException $e) {\n    if (str_contains($e->getMessage(), 'Invalid UserControl user id')) {\n        throw new BadRequestException('Invalid user id supplied.');\n    }\n    throw $e;\n}","preventionTips":["Validate route/query UUID parameters in controllers before passing them downstream.","Never pass numeric legacy ids where a UUID is expected.","Use Cake's uuid validation rule at the form/request boundary consistently."],"tags":["validation","uuid","access-control"],"backgroundTag":"invalid-identifier-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"}