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

  1. Send the user's UUID (the `id` field returned by /users.json) in the URL.
  2. Use GET /users/me.json when the target is the currently authenticated user.
  3. Fix the client to resolve emails/usernames to UUIDs via the user index endpoint first.
  4. 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

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


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)