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
- Ensure every batch entry has an `id` key holding a valid UUID string (e.g. 8-4-4-4-12 hex).
- Run Cake\Validation\Validation::uuid($id) on each identifier client-side before sending.
- Fix key naming so the entity identifier is under `id`, not `resource_id`/`folder_id`.
- 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
- Always use UUID strings for entity identifiers, never numeric row ids
- Name the identifier key `id`, not `resource_id`/`folder_id`
- Validate ids with Validation::uuid() or a regex before sending
- Watch for truncated/malformed UUIDs produced by string slicing or serializers
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
- The identifier should be a valid UUID.
- The SSO setting id should be a uuid.
- The SSO setting id should be a uuid.
- Invalid id
- Invalid status.
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)