passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException
The user identifier should be a valid UUID or "me".
Error message
The user identifier should be a valid UUID or "me".
What it means
GET /users/<id>.json validates that the user identifier in the URL is either a valid UUID or the literal string "me". Any other token (username, e-mail address, numeric id) fails Validation::uuid() and is rejected with a 400 BadRequestException before the database is queried.
Solutions
- Send the user's UUID (the `id` field returned by /users.json) in the URL.
- Use GET /users/me.json when the target is the currently authenticated user.
- Fix the client to resolve emails/usernames to UUIDs via the user index endpoint first.
- Ensure the id is not URL-mangled (no spaces, full 36-char UUID).
Example fix
// before
fetch('/users/alice@example.com.json')
// after
fetch('/users/782609da-397c-4a52-9f4c-8a0f3d5f2a01.json')
// or
fetch('/users/me.json') 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;
function canCallUserView(id) { return id === 'me' || UUID_RE.test(id); }
if (!canCallUserView(id)) throw new TypeError(`Expected UUID or 'me', got: ${id}`); Type guard
function isUserIdentifier(v) {
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
return typeof v === 'string' && (v === 'me' || UUID_RE.test(v));
} Try / catch
try {
const res = await api.get(`/users/${id}.json`);
} catch (e) {
if (e.response?.status === 400) {
throw new Error(`'${id}' is not a valid user identifier: use a UUID or 'me'.`);
}
throw e;
} Prevention
- Always source ids from the API response `id` field, never from usernames/emails.
- Prefer /users/me.json for the logged-in user instead of tracking your own UUID.
- Validate UUIDs client-side with a regex before building URLs.
- Beware variable interpolation bugs producing 'undefined' or empty ids.
When it happens
Trigger: GET /users/{id}.json where {id} is not a UUID and not "me" — e.g. passing a username, email address, auto-increment id, or an empty/truncated string as the identifier.
Common situations: Clients storing/displaying user emails instead of UUIDs in URLs; older API v1 style numeric ids; URL-encoding mistakes that corrupt the UUID; frontend bugs where an undefined variable interpolates as a non-UUID string.
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
- Could not validate resource data.
- Could not validate the password policies settings.
- Invalid verify token format.
- The authentication token id is invalid.
- The comment id is not valid.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/13cbe8500d605015.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Users/UsersViewController.php:53
/**
* User View action
*
* @throws \Cake\Http\Exception\BadRequestException if the user id is not a uuid or 'me'
* @throws \Cake\Http\Exception\NotFoundException if the user does not exist
* @param string $id uuid|me
* @return void
*/
public function view(string $id)
{
$this->assertJson();
// Check request sanity
if (!Validation::uuid($id)) {
if ($id === 'me') {
$id = $this->User->id(); // me returns the currently logged-in user
} else {
throw new BadRequestException(__('The user identifier should be a valid UUID or "me".'));
}
}
// Retrieve the user
/** @var \App\Model\Table\UsersTable $usersTable */
$usersTable = $this->fetchTable('Users');
$query = $usersTable->findView($id, $this->User->role());
// Trigger an event to filter data, decorate results, add contain, etc.
$event = TableFindIndexBefore::create(
$query,
FindIndexOptions::createFromArray(['query' => $query]),
$usersTable
);
/** @var \App\Model\Event\TableFindIndexBefore $event */
$this->getEventManager()->dispatch($event);
$query = $event->getQuery();
View on GitHub (pinned to 31c1bbc10f)