passbolt/passbolt_api · error · BadRequestException
The resource identifier should be a valid UUID.
Error message
The resource identifier should be a valid UUID.
What it means
ResourcesTagsAddController::addPost() validates the resourceId route parameter with CakePHP Validation::uuid() before doing any work; a malformed id raises BadRequestException. This is a first-line input-format check on the URL.
Solutions
- Pass the passbolt resource UUID (36-char, e.g. from GET /resources.json)
- Fix client URL construction so the id placeholder is actually substituted
- Validate the id client-side with a UUID regex/validator before calling the endpoint
Example fix
// before
await api.put(`/resources-tags/${resource.id}`);
// after
if (!/^[0-9a-f-]{36}$/i.test(resource.id)) throw new Error('Invalid resource UUID');
await api.put(`/resources-tags/${resource.id}`); 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 (!UUID_RE.test(resourceId)) throw new Error('resourceId 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 { await addResourceTags(id, tags); } catch (e) { if (e.status === 400 && /UUID/.test(e.message)) { /* fix client id source */ } else throw e; } Prevention
- Always source ids from passbolt API responses, never local numeric ids
- Validate UUID format client-side before requests
- Check URL templates for unsubstituted placeholders
When it happens
Trigger: PUT/POST to /resources-tags/<resourceId> (or the tags-add route) where resourceId is not a UUID: numeric ids, slugs, empty strings, or truncated identifiers.
Common situations: Client code passing a database auto-increment id or a name instead of the passbolt resource UUID; URL templating bug that leaves a placeholder in the path; hand-crafted curl tests.
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
- Invalid verify token format.
- The identifier should be a valid UUID.
- The identifier should be a valid UUID.
- The metadata key ID should be a valid UUID.
- The role identifier is not valid.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/512b7cb9f5a4e258.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Tags/src/Controller/Tags/ResourcesTagsAddController.php:64
{
parent::initialize();
$this->Resources = $this->fetchTable('Resources');
$this->Tags = $this->fetchTable('Passbolt/Tags.Tags');
}
/**
* Add tags for a given resource.
* Providing an empty list of tags delete all the personal tags
*
* @param string $resourceId The identifier of the resource to add a comment to
* @throws \Cake\Http\Exception\BadRequestException
* @throws \Cake\Http\Exception\NotFoundException
* @return void
*/
public function addPost(string $resourceId)
{
if (!Validation::uuid($resourceId)) {
throw new BadRequestException(__('The resource identifier should be a valid UUID.'));
}
$uac = $this->User->getAccessControl();
$data = $this->formatRequestData();
$data = $this->validateRequestData($data, $uac);
$options = ['contain' => ['all_tags' => 1, 'permission' => 1]];
/** @var \App\Model\Entity\Resource|null $resource */
$resource = $this->Resources->findView($uac->getId(), $resourceId, $options)->first();
if (is_null($resource)) {
throw new NotFoundException(__('The resource does not exist.'));
}
$tags = (new ResourcesTagsAddService())->add($uac, $resource, $data);
$tags = (new MetadataTagsRenderService())->renderTags($tags);
$this->success(__('The operation was successful.'), $tags);
}
View on GitHub (pinned to 31c1bbc10f)