passbolt/passbolt_api · error · BadRequestException

The group id is not valid.

Error message

The group id is not valid.

What it means

UUID guard in GroupsViewController::view(): the {id} path parameter must be a valid UUID of a group. Fires when the client requests a group with a malformed identifier, rejecting with HTTP 400 before any database lookup; a valid id for a missing group yields NotFoundException ('The group does not exist.').

Solutions

  1. Inspect the URL actually requested and confirm the id segment is a 36-char UUID (8-4-4-4-12 hex)
  2. Fix the client code to pass the group's UUID from GET /groups.json
  3. If you only have a name, resolve it to a UUID first via the groups index endpoint
  4. Validate the id client-side with a UUID regex before calling

Example fix

// before
const url = `/groups/${group.id}.json`; // group.id was a numeric legacy id
// after
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(groupId)) {
  throw new Error('group id must be a UUID');
}
const url = `/groups/${groupId}.json`;
Defensive patterns

Strategy: validation

Validate before calling

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);
if (!isUuid(groupId)) throw new Error('group id must be a UUID, got: ' + groupId);

Type guard

const asGroupUuid = (v) => isUuid(v) ? v : null;

Try / catch

if (!isUuid(id)) { id = await resolveGroupIdByName(name); }

Prevention

When it happens

Trigger: GET /groups/<id>.json with a non-UUID id: numeric legacy id, truncated string, URL-encoded garbage, or an empty segment resulting in a route mismatch/malformed call.

Common situations: Old integrations built before passbolt used UUIDs; string concatenation bugs building the URL; reading the wrong column (e.g. user id instead of group id) from another API response; trimming/truncation by a proxy or client.

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/a6a8b1dfcc49559e. Report an issue: GitHub.

Appendix: source

Thrown at src/Controller/Groups/GroupsViewController.php:44

 * @property \App\Model\Table\GroupsTable $Groups
 */
class GroupsViewController extends AppController
{
    /**
     * Group View action
     *
     * @throws \Cake\Http\Exception\BadRequestException if the group id is not a uuid
     * @throws \Cake\Http\Exception\NotFoundException if the group does not exist
     * @param string $id uuid Identifier of the group
     * @return void
     */
    public function view(string $id)
    {
        $this->assertJson();

        // Check request sanity
        if (!Validation::uuid($id)) {
            throw new BadRequestException(__('The group id is not valid.'));
        }
        /** @var \App\Model\Table\GroupsTable $groupsTable */
        $groupsTable = $this->fetchTable('Groups');

        // Retrieve and sanity the query options.
        $whitelist = [
            'contain' => [
                'modifier', 'modifier.profile', 'my_group_user',
                'users', 'groups_users', 'groups_users.user',
                'groups_users.user.profile', 'groups_users.user.gpgkey',
                // Deprecated contains, use plural form instead
                // @deprecated remove when v2 support is dropped
                'user', 'group_user', 'group_user.user', 'group_user.user.profile',
                'group_user.user.gpgkey',
            ],
        ];
        $options = $this->QueryString->get($whitelist);
        if (isset($options['contain']['my_group_user'])) {

View on GitHub (pinned to 31c1bbc10f)