passbolt/passbolt_api · error · BadRequestException

The identifier should be a valid UUID.

Error message

The identifier should be a valid UUID.

What it means

In MetadataBatchUpdateValidationService::validateMany, after the array check each entry must carry a valid UUID in its `id` field; Validation::uuid() failure throws this BadRequestException. The IDs are then used to load the entities, so invalid identifiers abort the whole batch.

Solutions

  1. Ensure every batch entry has an `id` key holding a valid UUID string (e.g. 8-4-4-4-12 hex).
  2. Run Cake\Validation\Validation::uuid($id) on each identifier client-side before sending.
  3. Fix key naming so the entity identifier is under `id`, not `resource_id`/`folder_id`.
  4. Reject/repair malformed entries before the batch call instead of letting the whole batch fail.

Example fix

// before
{"id": "12345"}

// after
{"id": "8e1a4b60-1c2f-4b3a-9c8d-0e5f6a7b8c9d"}
Defensive patterns

Strategy: validation

Validate before calling

use Cake\Validation\Validation;
foreach ($batch as $entry) {
    if (!isset($entry['id']) || !Validation::uuid($entry['id'])) {
        throw new InvalidArgumentException('Batch entry id must be a valid UUID');
    }
}

Type guard

function isUuid(mixed $v): bool {
    return is_string($v) && preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $v) === 1;
}

Try / catch

try {
    $data = $service->validateMany($requestData);
} catch (BadRequestException $e) {
    // sanitize ids: repair/extract UUIDs then resubmit, or report bad entry
}

Prevention

When it happens

Trigger: Batch metadata update requests where an entry's `id` is missing, null, empty, an integer, or otherwise not a RFC 4122 UUID; calling validateMany with entities whose identifier key was renamed or not provided.

Common situations: Scripts passing resource/folder row numbers instead of UUIDs; payloads using a wrong key (e.g. `resource_id`) so `id` resolves to null; UUIDs truncated or quoted inconsistently by a serializer.

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

Appendix: source

Thrown at plugins/PassboltCe/Metadata/src/Model/Validation/MetadataBatchUpdateValidationService.php:62

    abstract public function getForm(): MetadataBatchUpgradeForm;

    /**
     * @param array $requestData Request data.
     * @return array
     * @throws \Cake\Http\Exception\BadRequestException If data is invalid.
     * @throws \App\Error\Exception\CustomValidationException If data is invalid.
     * @throws \Cake\Http\Exception\NotFoundException If one or more resources are not found.
     */
    public function validateMany(array $requestData): array
    {
        foreach ($requestData as $values) {
            if (!is_array($values)) {
                throw new BadRequestException(__('The entity must be an array.'));
            }

            $id = $values['id'] ?? null;
            if (!Validation::uuid($id)) {
                throw new BadRequestException(__('The identifier should be a valid UUID.'));
            }
        }

        $entityIds = Hash::extract($requestData, '{n}.id');
        $this->entities = $this->queryEntitiesFromIds($entityIds)->all()->toArray();
        // Re-arrange entities array to set key as identifier and value as entity object to easily find it
        $this->entities = Hash::combine($this->entities, '{n}.id', '{n}');

        $data = [];
        $errors = [];
        foreach ($requestData as $i => $entity) {
            $entityId = $entity['id'];
            if (!array_key_exists($entityId, $this->entities)) {
                throw new NotFoundException(__('Entity {0} not found.', $entityId));
            }

            /** @var \Passbolt\Metadata\Model\Entity\MetadataKey|null $metadataKey */
            $metadataKey = $this->entities[$entityId]['metadata_key'] ?? null;

View on GitHub (pinned to 31c1bbc10f)