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

  1. Use the target user's passbolt UUID in the URL path
  2. Resolve the id via GET /users.json (admin endpoint) and use its id field
  3. Validate the id format client-side before calling the endpoint
  4. 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

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


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)