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
Passbolt throws this 400 when the DELETE /resources/<id> path parameter is not a valid UUID. ResourcesDeleteController::delete validates with Validation::uuid() before attempting to load the resource.
Solutions
- Fetch the resource UUID from GET /resources.json and retry DELETE with it
- Add a UUID format check before issuing the DELETE
- Fix client code to pass the entity's id property, not name/slug
- Check for URL-encoding or truncation issues if the id appears correct in source
Example fix
// before
await api.del(`/resources/${row.name}.json`);
// after
if (!/^[0-9a-f-]{36}$/i.test(row.id)) throw new Error('invalid resource id');
await api.del(`/resources/${row.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('delete requires a resource UUID'); Type guard
const deletable = (r) => isUuid(r?.id) && r.personal === false ? r.id : null;
Try / catch
if (!isUuid(id)) { id = await lookupIdFromIndex(name); } Prevention
- Fetch ids from the resources index before destructive calls
- Add a dry-run/list step in deletion scripts
- Sanitize variables interpolated into DELETE URLs
When it happens
Trigger: DELETE /resources/<id>.json with numeric/slug/empty/truncated id segments from malformed client calls or legacy id schemes.
Common situations: Scripts iterating over a list where a name or index was passed instead of the id; string slicing bugs; older integrations built for numeric ids; double URL-encoding corrupting the UUID.
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 identifier should be a 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/85d3ab143b3d1a05.
Report an issue: GitHub.
Appendix: source
Thrown at src/Controller/Resources/ResourcesDeleteController.php:81
/**
* Resource Delete action
*
* @param string $id The identifier of the resource to delete.
* @throws \Cake\Http\Exception\NotFoundException If the resource does not exist.
* @throws \Cake\Http\Exception\NotFoundException If the resource is soft deleted.
* @throws \Cake\Http\Exception\NotFoundException If the user does not have access to the resource.
* @throws \Cake\Http\Exception\ForbiddenException If the user does not have the permission to delete the resource.
* @throws \Cake\Http\Exception\BadRequestException If the resource id is not a valid uuid.
* @throws \Cake\Http\Exception\InternalErrorException if the resource could not be saved for other reasons
* @return void
*/
public function delete(string $id): void
{
$this->assertJson();
// Check request sanity
if (!Validation::uuid($id)) {
throw new BadRequestException(__('The resource identifier should be a valid UUID.'));
}
// Retrieve the resource to delete.
try {
/** @var \App\Model\Entity\Resource $resource */
$resource = $this->Resources->find()
->contain(['ResourceTypes'])
->where(['Resources.id' => $id])
->firstOrFail();
$originalResource = clone $resource;
} catch (RecordNotFoundException $e) {
throw new NotFoundException(__('The resource does not exist.'));
}
// Get the list of users who have access to the resource
// useful to do now to notify users later, since it wont be possible to after delete
// The logged in user will not be notified.
$options = ['contain' => ['role'], 'filter' => ['has-access' => [$resource->id]]];View on GitHub (pinned to 31c1bbc10f)