passbolt/passbolt_api · error · InvalidArgumentException
The user ID should be a valid UUID.
Error message
The user ID should be a valid UUID.
What it means
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.
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.
Example fix
// before
$service->getActiveRefreshToken($token, $user['username']); // email, not UUID
// after
if (!Validation::uuid($userId)) { throw new BadRequestException(); }
$service->getActiveRefreshToken($token, $userId); Defensive patterns
Strategy: validation
Validate before calling
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
if (!UUID_RE.test(userId ?? '')) throw new Error('userId must be a UUID'); Type guard
function isUuid(v: unknown): v is string {
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);
} Try / catch
try {
$service->validateUserId($userId);
} catch (InvalidArgumentException $e) {
throw new BadRequestException('userId must be a valid UUID', 400, $e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Invalid user ID format.
- " " is not a valid group id for filter .
- " " is not a valid parent id for filter .
- " " is not a valid user id for filter .
- Invalid id
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/b7e5f7e0fd7747da.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/JwtAuthentication/src/Service/RefreshToken/RefreshTokenAbstractService.php:138
* @return void
* @throws \InvalidArgumentException If the token is not a valid UUID
*/
public function validateRefreshToken(mixed $token): void
{
if (!Validation::uuid($token)) {
throw new InvalidArgumentException(__('The refresh token should be a valid UUID.'));
}
}
/**
* @param mixed $userId User id to be validated.
* @return void
* @throws \InvalidArgumentException if the $id is not valid
*/
public function validateUserId(mixed $userId): void
{
if (!Validation::uuid($userId)) {
throw new InvalidArgumentException(__('The user ID should be a valid UUID.'));
}
}
/**
* @param string|null $token Refresh token
* @return \Cake\ORM\Query\SelectQuery
* @throws \InvalidArgumentException If the token is not a valid UUID
*/
public function queryRefreshToken(?string $token): SelectQuery
{
$this->validateRefreshToken($token);
return $this->AuthenticationTokens->find()->where([
'token' => $token,
'type' => AuthenticationToken::TYPE_REFRESH_TOKEN,
]);
}
View on GitHub (pinned to 31c1bbc10f)