{"record":{"id":"df598cc35bfa4d51","repo":"passbolt/passbolt_api","slug":"the-refresh-token-should-be-a-valid-uuid","errorCode":null,"errorMessage":"The refresh token should be a valid UUID.","messagePattern":"The refresh token should be a valid UUID\\.","errorType":"validation","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"plugins/PassboltCe/JwtAuthentication/src/Service/RefreshToken/RefreshTokenAbstractService.php","lineNumber":126,"sourceCode":"\n        // Reflect the persisted state on the returned entity so callers do not operate on stale data\n        $refreshToken->set('active', false);\n        $refreshToken->set('modified', $modified);\n        $refreshToken->setDirty('active', false);\n        $refreshToken->setDirty('modified', false);\n\n        return $refreshToken;\n    }\n\n    /**\n     * @param mixed $token Refresh token to be validated.\n     * @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","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Service/RefreshToken/RefreshTokenAbstractService.php#L108-L144","documentation":"validateRefreshToken rejects any refresh token that is not a valid UUID via CakePHP's Validation::uuid(), throwing InvalidArgumentException before any database lookup. Passbolt refresh tokens are AuthenticationToken entities keyed by UUID, so a non-UUID can never match and is rejected early as invalid input.","triggerScenarios":"Calling queryRefreshToken or getUserIdFromToken (or the refresh/logout endpoints) with a null, empty, truncated, or otherwise malformed token string (e.g. 'abc123', a JWT access token mistakenly sent as the refresh token, or a base64 string).","commonSituations":"Confusing the JWT access token (long dot-separated string) with the UUID refresh token; sending the raw cookie value instead of the token id; copying a token with truncation or extra quoting; old clients from before refresh tokens were UUIDs.","solutions":["Send the refresh token exactly as issued: a UUID string (e.g. returned by the refresh/login endpoints).","Validate the token client-side with a UUID regex /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i before calling the API.","Check you are not sending the access token in the refresh-token field of the request body.","Wrap calls in a try/catch for InvalidArgumentException and surface a 400-style input error instead of proceeding."],"exampleFix":"// before\nawait service.getUserIdFromToken(accessToken); // JWT, not a UUID\n// after\nif (!/^\\h{8}-\\h{4}-\\h{4}-\\h{4}-\\h{12}$/i.test(refreshToken)) throw new Error('refresh token must be a UUID');\nawait service.getUserIdFromToken(refreshToken);","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(refreshToken ?? '')) throw new Error('refresh token 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->validateRefreshToken($token);\n} catch (InvalidArgumentException $e) {\n  throw new BadRequestException('refresh_token must be a valid UUID', 400, $e);\n}","preventionTips":["Send the UUID refresh token, never the JWT access token, in the refresh_token field","Validate UUID format client-side before network calls","Trim/unescape tokens copied from storage or logs"],"tags":["validation","uuid","refresh-token","jwt"],"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-21T04:17:39.646Z"}