passbolt/passbolt_api · warning · BadRequestException
The user identifier should be a UUID.
Error message
The user identifier should be a UUID.
What it means
A BadRequestException thrown by UserMetadataKeysDeleteService::delete when the provided $userId is not a valid UUID. This public service method is the entry point for removing a user's metadata private keys and session keys; it validates the identifier format before touching the database.
Solutions
- Pass the user's actual UUID (as found in the users table / GET /users.json response)
- Validate the identifier client-side with a UUID check (CakePHP Validation::uuid or a regex) before calling delete
- Fix the caller/route so the correct path segment is used as the user ID
Example fix
// before
$service->delete($user['username']);
// after
if (!Validation::uuid($userId)) {
throw new BadRequestException(__('The user identifier should be a UUID.'));
}
$service->delete($userId); Defensive patterns
Strategy: validation
Validate before calling
use Cake\Validation\Validation;
if (!Validation::uuid($userId)) {
throw new \InvalidArgumentException('userId must be a UUID');
}
$service->delete($userId); Type guard
function isValidUuid(?string $id): bool {
return is_string($id) && (bool) preg_match('/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', $id);
} Try / catch
try {
$service->delete($userId);
} catch (BadRequestException $e) {
// userId was not a UUID: fix the identifier source
} Prevention
- Always resolve users via the users table/API to obtain their UUID before deleting metadata keys
- Validate identifiers with Validation::uuid at the call site
- Check route templates bind the correct segment to userId
- Avoid passing usernames/emails where UUIDs are expected
When it happens
Trigger: Calling the user metadata keys delete service/endpoint with a malformed user identifier — empty string, numeric ID, slug, or truncated UUID instead of a 36-char UUID.
Common situations: Client code passing a username or non-UUID identifier; copy-paste errors of user IDs; routing bugs where the wrong URL segment is bound to the userId parameter; scripted cleanups iterating over non-UUID keys.
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 authentication token id is invalid.
- The request data is invalid: id invalid.
- The resource identifier should be a valid UUID.
- The role identifier is not valid.
- The user id is invalid.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/01b8e86cd0546b01.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Metadata/src/Service/UserMetadataKeysDeleteService.php:38
use Cake\Http\Exception\InternalErrorException;
use Cake\ORM\Locator\LocatorAwareTrait;
use Cake\Utility\Hash;
use Cake\Validation\Validation;
class UserMetadataKeysDeleteService
{
use LocatorAwareTrait;
/**
* Delete user metadata private & session keys.
*
* @param string $userId User identifier.
* @return void
*/
public function delete(string $userId): void
{
if (!Validation::uuid($userId)) {
throw new BadRequestException(__('The user identifier should be a UUID.'));
}
$this->deleteMetadataPrivateKeys($userId);
$this->deleteMetadataSessionKeys($userId);
}
/**
* @param string $userId User identifier.
* @return void
* @throws \Cake\Http\Exception\InternalErrorException If data is not deleted.
*/
private function deleteMetadataPrivateKeys(string $userId): void
{
/** @var \Passbolt\Metadata\Model\Table\MetadataPrivateKeysTable $metadataPrivateKeysTable */
$metadataPrivateKeysTable = $this->fetchTable('Passbolt/Metadata.MetadataPrivateKeys');
$metadataPrivateKeys = $metadataPrivateKeysTable
->unhydratedFind()View on GitHub (pinned to 31c1bbc10f)