passbolt/passbolt_api · error · InvalidArgumentException
Invalid user ID format.
Error message
Invalid user ID format.
What it means
Thrown by populatedMetadataUserKeyId when the supplied $userId is not a valid UUID (Validation::uuid fails). The trait uses the user ID to populate metadata user key ids in request data, and refuses to proceed with a malformed identifier.
Solutions
- Pass a valid UUID string (36 chars, canonical 8-4-4-4-12 hex format) as $userId
- Validate the id client-side before calling, e.g. with the same UUID regex used by CakePHP Validation::uuid()
- Check routing/config so the user id is correctly bound to the action parameter
- If the id comes from an entity, use $entity->id rather than a manually supplied value
Example fix
// before
$service->populatedMetadataUserKeyId($userId, $data); // $userId = 'admin'
// after
if (!Validation::uuid($userId)) {
throw new BadRequestException(__('A valid user identifier is required.'));
}
$service->populatedMetadataUserKeyId($userId, $data); Defensive patterns
Strategy: validation
Validate before calling
use Cake\Validation\Validation;
if (!is_string($userId) || !Validation::uuid($userId)) {
throw new BadRequestException(__('Invalid user ID.'));
} Type guard
function isUuidString(mixed $value): bool {
return is_string($value) && (bool)preg_match('/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i', $value);
} Try / catch
try {
$data = $trait->populatedMetadataUserKeyId($userId, $data);
} catch (InvalidArgumentException $e) {
return $this->response->withStatus(400)->withStringBody(json_encode(['error' => 'Invalid user ID format']));
} Prevention
- Always source user ids from entity ->id, not user input like username/email
- Validate route parameters as UUIDs before calling services
- Use CakePHP route type constraints (uuid placeholder) in routes.php
- Add a pre-call Validation::uuid() assertion in controllers
When it happens
Trigger: Calling a controller/service action using this trait with a user ID that is null, empty, non-UUID string, or an integer id instead of a UUID string; routing parameters bound incorrectly so the id placeholder holds something else.
Common situations: Passing a username/email or numeric legacy id where a UUID is expected; URL building mistakes that omit the id segment; tests or CLI code constructing request data with dummy ids.
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 metadata key ID should be a valid UUID.
- The parent task identifier should be a valid UUID.
- " " is not a valid group id for filter .
- " " is not a valid parent id for filter .
- " " is not a valid user id for filter .
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/81553310d827fb5e.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Metadata/src/Utility/MetadataPopulateUserKeyIdTrait.php:39
use Cake\Validation\Validation;
use InvalidArgumentException;
use Passbolt\Metadata\Model\Dto\MetadataDto;
use Passbolt\Metadata\Model\Entity\MetadataKey;
trait MetadataPopulateUserKeyIdTrait
{
/**
* Update sent v5 entities request data when METADATA_KEY_TYPE TYPE_USER_KEY is set to null
* By dynamically inserting the current gpgkey_id in its place
*
* @param string $userId uuid
* @param mixed $data request data
* @return array
*/
public function populatedMetadataUserKeyId(string $userId, mixed $data): array
{
if (!Validation::uuid($userId)) {
throw new InvalidArgumentException(__('Invalid user ID format.'));
}
if (!isset($data) || !is_array($data)) {
throw new BadRequestException(__('The data is required.'));
}
if (
isset($data[MetadataDto::METADATA])
&& isset($data[MetadataDto::METADATA_KEY_TYPE])
&& is_string($data[MetadataDto::METADATA_KEY_TYPE])
&& $data[MetadataDto::METADATA_KEY_TYPE] === MetadataKey::TYPE_USER_KEY
&& !isset($data[MetadataDto::METADATA_KEY_ID])
) {
$keyTable = TableRegistry::getTableLocator()->get('Gpgkeys');
$key = $keyTable->find('current', userId: $userId)->firstOrFail();
$id = $key->get('id');
if (Validation::uuid($id)) {
$data[MetadataDto::METADATA_KEY_ID] = $id;
}
}View on GitHub (pinned to 31c1bbc10f)