passbolt/passbolt_api · error · BadRequestException
The user identifier should be a valid UUID.
Error message
The user identifier should be a valid UUID.
What it means
Thrown by the AuditLog EE plugin's UserLogsController after the admin check passes, when the userId path parameter is not a valid UUID. Only administrators can view user logs, and the controller validates identifier format before checking user existence.
Solutions
- Use the target user's passbolt UUID in the URL path
- Resolve the id via GET /users.json (admin endpoint) and use its id field
- Validate the id format client-side before calling the endpoint
- Ensure the caller is authenticated as an administrator so the request passes the preceding admin assertion
Example fix
// before
get(`/users/${user.profile.username}/logs.json`);
// after
get(`/users/${user.id}/logs.json`); // UUID 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 (!isAdmin()) throw new Error('Admin role required');
if (!UUID_RE.test(userId)) throw new Error('userId must be a UUID'); Type guard
const isUuid = (v) => 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 {
const logs = await getUserLogs(userId);
} catch (e) {
if (e.code === 400 && /valid UUID/.test(e.message)) {
console.error('Invalid user id format:', userId);
} else if (e.code === 403) {
console.error('Admin role required');
} else { throw e; }
} Prevention
- Remember the endpoint is admin-only — check role before calling
- Resolve user ids from GET /users.json rather than usernames
- Validate UUID format before the request
- Avoid undefined interpolations in URL templates
When it happens
Trigger: GET /users/<userId>/logs.json called by a non-UUID identifier (empty, numeric, slug), even when the caller is an authenticated admin.
Common situations: Admin tooling or scripts iterating with wrong identifiers; UI bug passing undefined into the URL; tests using placeholder ids; users without admin rights hitting this after the earlier admin assertion differently — but the specific 400 here is purely format-related.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- The folder identifier should be a valid UUID.
- The resource identifier should be a valid UUID.
- The comment id is not valid.
- The group id is not valid.
- The group identifier should be a valid UUID.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/78ddf6105c4534d2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AuditLog/src/Controller/UserLogsController.php:51
return 'Users';
}
/**
* View action logs for a given user.
*
* @param string|null $userId user id
* @return void
* @throws \Cake\Http\Exception\BadRequestException if the user id has the wrong format
* @throws \Cake\Http\Exception\ForbiddenException if the UAC is not admin
* @throws \Cake\Http\Exception\NotFoundException if the user does not exist
*/
public function view(?string $userId = null)
{
$this->User->assertIsAdmin(__('Only administrators can view user logs.'));
// Check request sanity
if (!Validation::uuid($userId)) {
throw new BadRequestException(__('The user identifier should be a valid UUID.'));
}
if (!TableRegistry::getTableLocator()->get('Users')->exists(['id' => $userId])) {
throw new NotFoundException(__('The user does not exist.'));
}
$this->viewByEntity(new UserActionLogsFinder(), $userId);
}
}
View on GitHub (pinned to 31c1bbc10f)