passbolt/passbolt_api · error · Cake\Http\Exception\BadRequestException

The user identifier should be a valid UUID.

Error message

The user identifier should be a valid UUID.

What it means

UserScimResource::setFromDatabase() expects the passbolt internal user identifier to be a valid UUID (it is used as a direct lookup key on the users table). CakePHP's Validation::uuid() rejects anything else and a BadRequestException is thrown before any database query, protecting against malformed identifiers.

Solutions

  1. Pass the passbolt users.id UUID (36-char, 8-4-4-4-12 hex) to setFromDatabase().
  2. If you have a SCIM id or externalId, resolve it via ScimEntries table to the internal UUID first.
  3. Validate the id with Cake\Util\Validation::uuid() before calling.
  4. Check where the id is extracted from (URL path, lookup map) for corruption.

Example fix

// before
$userScimResource->setFromDatabase($scimEntry->external_identifier);
// after
$userScimResource->setFromDatabase($scimEntry->foreign_model_id); // internal users.id UUID
Defensive patterns

Strategy: validation

Validate before calling

use Cake\Validation\Validation;
if (!Validation::uuid($internalId)) {
    throw new InvalidArgumentException('Internal user id must be a UUID, got: ' . var_export($internalId, true));
}

Type guard

function isUuid(mixed $id): bool {
    return is_string($id) && (bool)preg_match(
        '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $id);
}

Try / catch

try {
    $resource->setFromDatabase($internalId);
} catch (BadRequestException $e) {
    // resolve the correct internal UUID before retrying
}

Prevention

When it happens

Trigger: Calling setFromDatabase() with a non-UUID string (numeric DB id, SCIM externalId passed by mistake, empty string), from create/patch/put flows.

Common situations: Developer confuses SCIM externalId with passbolt's internal UUID; passes a legacy integer id; trims/loses part of the id in URL parsing; hardcoded test id.

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


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/f0fd2401e0add592. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Scim/src/Utility/Resource/UserScimResource.php:224

    /**
     * @param array $data
     * @return void
     */
    protected function validateScimUserData(array $data): void
    {
        $schemas = $data['schemas'] ?? [];
        if (!in_array(SchemaIdentifier::CORE_USER, $schemas)) {
            throw new BadRequestException('Invalid schema for SCIM User Resource');
        }
    }

    /**
     * @inheritDoc
     */
    public function setFromDatabase(string $internalId): self
    {
        if (!Validation::uuid($internalId)) {
            throw new BadRequestException(__('The user identifier should be a valid UUID.'));
        }
        /** @var \App\Model\Entity\User|null $userEntity */
        $userEntity = $this->Users
            ->findForScim([$this->Users->aliasField('id') => $internalId], findDeleted: true)
            ->contain(['Profiles', 'ScimEntries'])
            ->first();
        $this->userEntity = $userEntity;
        if (!$this->userEntity) {
            throw new ResourceNotFoundException(
                sprintf('The %s resource with id `%s` was not found', $this->getType(), $internalId)
            );
        }
        if ($this->userEntity->deleted) {
            throw new ResourceNotFoundException(
                sprintf('The %s resource with id `%s` is already deleted', $this->getType(), $internalId)
            );
        }

View on GitHub (pinned to 31c1bbc10f)