{"record":{"id":"b7e5f7e0fd7747da","repo":"passbolt/passbolt_api","slug":"the-user-id-should-be-a-valid-uuid","errorCode":null,"errorMessage":"The user ID should be a valid UUID.","messagePattern":"The user ID should be a valid UUID\\.","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"plugins/PassboltCe/JwtAuthentication/src/Service/RefreshToken/RefreshTokenAbstractService.php","lineNumber":138,"sourceCode":"     * @return void\n     * @throws \\InvalidArgumentException If the token is not a valid UUID\n     */\n    public function validateRefreshToken(mixed $token): void\n    {\n        if (!Validation::uuid($token)) {\n            throw new InvalidArgumentException(__('The refresh token should be a valid UUID.'));\n        }\n    }\n\n    /**\n     * @param mixed $userId User id to be validated.\n     * @return void\n     * @throws \\InvalidArgumentException if the $id is not valid\n     */\n    public function validateUserId(mixed $userId): void\n    {\n        if (!Validation::uuid($userId)) {\n            throw new InvalidArgumentException(__('The user ID should be a valid UUID.'));\n        }\n    }\n\n    /**\n     * @param string|null $token Refresh token\n     * @return \\Cake\\ORM\\Query\\SelectQuery\n     * @throws \\InvalidArgumentException If the token is not a valid UUID\n     */\n    public function queryRefreshToken(?string $token): SelectQuery\n    {\n        $this->validateRefreshToken($token);\n\n        return $this->AuthenticationTokens->find()->where([\n            'token' => $token,\n            'type' => AuthenticationToken::TYPE_REFRESH_TOKEN,\n        ]);\n    }\n","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Service/RefreshToken/RefreshTokenAbstractService.php#L120-L156","documentation":"validateUserId throws InvalidArgumentException when the supplied user id is not a valid UUID. Refresh token queries are scoped by (token, user_id); a malformed user id can never match a row, so it is rejected before querying the database.","triggerScenarios":"Calling queryRefreshTokenWithUserId or getActiveRefreshToken with a null, empty, or malformed userId string (e.g. an email address, an integer id, or a truncated UUID) during logout or token renewal flows.","commonSituations":"Passing the username/email instead of the user UUID; using the token id where the user id is expected; reading the wrong field off the authenticated session payload; string truncation when serializing ids.","solutions":["Pass the user's UUID (users.id from the database / the 'sub' claim of the access token).","Validate with a UUID regex before calling the API.","Confirm you are not swapping the token and userId arguments to getActiveRefreshToken(string $token, string $userId).","Catch InvalidArgumentException and return a client input error rather than querying."],"exampleFix":"// before\n$service->getActiveRefreshToken($token, $user['username']); // email, not UUID\n// after\nif (!Validation::uuid($userId)) { throw new BadRequestException(); }\n$service->getActiveRefreshToken($token, $userId);","handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nif (!UUID_RE.test(userId ?? '')) throw new Error('userId must be a UUID');","typeGuard":"function isUuid(v: unknown): v is string {\n  return typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v);\n}","tryCatchPattern":"try {\n  $service->validateUserId($userId);\n} catch (InvalidArgumentException $e) {\n  throw new BadRequestException('userId must be a valid UUID', 400, $e);\n}","preventionTips":["Pass users.id UUIDs, never emails or integer ids","Check argument order on getActiveRefreshToken(string $token, string $userId)","Read the user id from the token's 'sub' claim or authenticated identity, not display fields"],"tags":["validation","uuid","user-id"],"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-21T04:17:39.646Z"}