passbolt/passbolt_api · error · BadRequestException
The identifier should be a valid UUID.
Error message
The identifier should be a valid UUID.
What it means
Passbolt throws this 400 when the acoForeignKey path parameter of the permissions view endpoint is not a valid UUID. PermissionsViewController::viewAcoPermissions validates with Validation::uuid() before any lookup.
Solutions
- Ensure the path parameter is the resource's UUID obtained from GET /resources.json
- Add client-side UUID validation before the request
- Fix URL construction to interpolate the id field, not name or legacy numeric id
- Check logs/proxies for id truncation if the id looks correct in code
Example fix
// before
const url = `/permissions/resource/${resource.slug}.json`;
// after
if (!isUuid(resource.id)) throw new Error('expected resource UUID');
const url = `/permissions/resource/${resource.id}.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(resourceId)) throw new Error('acoForeignKey must be a resource UUID'); Type guard
const asResourceId = (r) => isUuid(r?.id) ? r.id : null;
Try / catch
if (!isUuid(id)) id = await resolveResourceId(resource);
Prevention
- Pass entity.id, never slug/name/legacy numeric id
- Validate format before URL construction
- Watch for double URL-encoding corrupting UUIDs
When it happens
Trigger: GET /permissions/resource/<acoForeignKey>.json with a non-UUID identifier: numeric id, slug, empty string, or an id that got mangled/truncated in transit.
Common situations: Legacy integrations using integer resource ids; concatenating the wrong variable into the URL; a client parsing a display name instead of the id; URL encoding issues dropping characters.
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 comment id is not valid.
- The group id is not valid.
- The group identifier should be a valid UUID.
- The permissions identifiers must be valid UUID.
- The resource identifier should be a valid UUID.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/ef3815553833feed.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Permissions/PermissionsViewController.php:69
/**
* View permissions defined for an aco instance.
* Only support the entity Resource for now.
*
* @param string $acoForeignKey The target aco id.
* @throws \Cake\Http\Exception\BadRequestException If the parameter acoForeignKey is null
* @throws \Cake\Http\Exception\BadRequestException If the parameter acoForeignKey is not a valid uuid
* @throws \Cake\Http\Exception\NotFoundException If the target resource doesn't exist
* @throws \Cake\Http\Exception\NotFoundException If the target resource is soft deleted
* @return void
*/
public function viewAcoPermissions(string $acoForeignKey)
{
$this->assertJson();
// Check request sanity
if (!Validation::uuid($acoForeignKey)) {
throw new BadRequestException(__('The identifier should be a valid UUID.'));
}
// Retrieve and sanity the query options.
$whitelist = ['contain' => ['group', 'user', 'user.profile']];
$options = $this->QueryString->get($whitelist);
// Check that the user has access to the resource.
$resource = $this->Resources->findView($this->User->id(), $acoForeignKey)->first();
if (empty($resource)) {
throw new NotFoundException(__('The resource does not exist.'));
}
// Retrieve the permissions.
$permissions = $this->Permissions->findViewAcoPermissions($acoForeignKey, $options);
$this->success(__('The operation was successful.'), $permissions);
}
}
View on GitHub (pinned to 31c1bbc10f)