{"record":{"id":"f0fd2401e0add592","repo":"passbolt/passbolt_api","slug":"the-user-identifier-should-be-a-valid-uuid-userscimresource","errorCode":null,"errorMessage":"The user identifier should be a valid UUID.","messagePattern":"The user identifier should be a valid UUID\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Scim/src/Utility/Resource/UserScimResource.php","lineNumber":224,"sourceCode":"    /**\n     * @param array $data\n     * @return void\n     */\n    protected function validateScimUserData(array $data): void\n    {\n        $schemas = $data['schemas'] ?? [];\n        if (!in_array(SchemaIdentifier::CORE_USER, $schemas)) {\n            throw new BadRequestException('Invalid schema for SCIM User Resource');\n        }\n    }\n\n    /**\n     * @inheritDoc\n     */\n    public function setFromDatabase(string $internalId): self\n    {\n        if (!Validation::uuid($internalId)) {\n            throw new BadRequestException(__('The user identifier should be a valid UUID.'));\n        }\n        /** @var \\App\\Model\\Entity\\User|null $userEntity */\n        $userEntity = $this->Users\n            ->findForScim([$this->Users->aliasField('id') => $internalId], findDeleted: true)\n            ->contain(['Profiles', 'ScimEntries'])\n            ->first();\n        $this->userEntity = $userEntity;\n        if (!$this->userEntity) {\n            throw new ResourceNotFoundException(\n                sprintf('The %s resource with id `%s` was not found', $this->getType(), $internalId)\n            );\n        }\n        if ($this->userEntity->deleted) {\n            throw new ResourceNotFoundException(\n                sprintf('The %s resource with id `%s` is already deleted', $this->getType(), $internalId)\n            );\n        }\n","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Scim/src/Utility/Resource/UserScimResource.php#L206-L242","documentation":"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.","triggerScenarios":"Calling setFromDatabase() with a non-UUID string (numeric DB id, SCIM externalId passed by mistake, empty string), from create/patch/put flows.","commonSituations":"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.","solutions":["Pass the passbolt users.id UUID (36-char, 8-4-4-4-12 hex) to setFromDatabase().","If you have a SCIM id or externalId, resolve it via ScimEntries table to the internal UUID first.","Validate the id with Cake\\Util\\Validation::uuid() before calling.","Check where the id is extracted from (URL path, lookup map) for corruption."],"exampleFix":"// before\n$userScimResource->setFromDatabase($scimEntry->external_identifier);\n// after\n$userScimResource->setFromDatabase($scimEntry->foreign_model_id); // internal users.id UUID","handlingStrategy":"validation","validationCode":"use Cake\\Validation\\Validation;\nif (!Validation::uuid($internalId)) {\n    throw new InvalidArgumentException('Internal user id must be a UUID, got: ' . var_export($internalId, true));\n}","typeGuard":"function isUuid(mixed $id): bool {\n    return is_string($id) && (bool)preg_match(\n        '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i', $id);\n}","tryCatchPattern":"try {\n    $resource->setFromDatabase($internalId);\n} catch (BadRequestException $e) {\n    // resolve the correct internal UUID before retrying\n}","preventionTips":["Only pass users.id UUIDs into setFromDatabase, never SCIM externalId.","Map externalId -> internal UUID via the scim_entries table when needed.","Keep identifiers as strings end-to-end to avoid int coercion.","Sanity-check id sources (URL params, DB rows) for truncation."],"tags":["scim","uuid","identifier"],"backgroundTag":"invalid-identifier-format","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}