{"record":{"id":"091533418d4134a6","repo":"passbolt/passbolt_api","slug":"could-not-validate-user-data","errorCode":null,"errorMessage":"Could not validate user data.","messagePattern":"Could not validate user data\\.","errorType":"validation","errorClass":"ValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/DirectorySync/src/Actions/UserSyncAction.php","lineNumber":142,"sourceCode":"    }\n\n    /**\n     * Update user\n     *\n     * @param \\App\\Model\\Entity\\User $existingUser User\n     * @param array $data data\n     * @return void\n     */\n    private function updateUser(User $existingUser, array $data): void\n    {\n        try {\n            $user = $this->Users->editEntity($existingUser, $data, new UserAccessControl(Role::ADMIN));\n            $result = $this->Users->save($user, ['checkrules' => false]);\n\n            if (!$result) {\n                if ($user->hasErrors()) {\n                    $msg = __('Could not validate user data.');\n                    throw new ValidationException($msg, $user, $this->Users);\n                }\n                throw new Exception('User could not be updated.');\n            }\n            // Send report.\n            $this->addReportItem(new ActionReport(\n                __(\n                    'The user {0} full name has been successfully updated to {1} {2}.',\n                    $existingUser->username,\n                    $user->profile->first_name,\n                    $user->profile->last_name\n                ),\n                Alias::MODEL_USERS,\n                Alias::ACTION_UPDATE,\n                Alias::STATUS_SUCCESS,\n                $user\n            ));\n        } catch (Exception $exception) {\n            $error = new SyncError($existingUser, $exception);","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/DirectorySync/src/Actions/UserSyncAction.php#L124-L160","documentation":"UserSyncAction::updateUser edits the existing user entity via UsersTable::editEntity with admin access control and saves it with checkrules=false; when the save fails and the entity carries validation errors, it wraps them in a ValidationException with the message 'Could not validate user data.' The entity's error set (attached to the exception) holds the per-field reasons. This corresponds to LDAP/AD directory data conflicting with passbolt's user validation rules.","triggerScenarios":"Directory sync updating a user where the incoming data violates model rules: invalid email format, username already taken by another account, too-short profile fields, role changes to a protected value, or editEntity's access-control rules rejecting the modification (e.g. editing hard-protected fields or a deactivated admin).","commonSituations":"Active Directory entries with emails passbolt considers invalid or duplicated (two LDAP users mapped to one passbolt email), renamed accounts colliding with existing usernames, sync configurations mapping wrong LDAP attributes (mail vs userPrincipalName) into user fields, or attempts to modify users that passbolt rules forbid changing during sync.","solutions":["Inspect the ValidationException's entity errors (getEntity()->getErrors()) to see exactly which fields failed, then fix the corresponding data in the directory or the mapping config.","Check for duplicate emails/usernames in the users table conflicting with the LDAP entry and resolve the collision (merge, rename, or deactivate the stale account).","Correct the DirectorySync email/attribute mapping configuration so valid LDAP attributes feed username/first_name/last_name.","If a legitimate edit is being blocked by field-level protection, perform it through the proper flow (e.g. admin UI) instead of sync, or adjust the data so it passes validation.","Catch ValidationException in the sync report layer so one bad user does not abort the whole directory sync run, and record the field errors in the ActionReport."],"exampleFix":"// before\n$result = $this->Users->save($user, ['checkrules' => false]);\n// after\n$result = $this->Users->save($user, ['checkrules' => false]);\nif (!$result) {\n    if ($user->hasErrors()) {\n        $errors = $user->getErrors(); // e.g. ['username' => ['_isUnique' => 'The username is already used.']]\n        $this->addReportItem(ActionReport::ERROR, 'The user data could not be validated.', json_encode($errors));\n        return; // skip user, continue sync\n    }\n    throw new Exception('User could not be updated.');\n}","handlingStrategy":"try-catch","validationCode":"use Cake\\Validation\\Validation;\nif (!Validation::email($data['username'] ?? '')) {\n    // fix or skip this directory entry before attempting the edit\n}\n$conflict = $usersTable->find()->where(['username' => $data['username'], 'id !=' => $existingUser->id])->first();\nif ($conflict !== null) { /* resolve duplicate username/email before sync */ }","typeGuard":null,"tryCatchPattern":"try {\n    $user = $this->Users->editEntity($existingUser, $data, new UserAccessControl(Role::ADMIN));\n    $this->Users->save($user, ['checkrules' => false]);\n} catch (ValidationException $e) {\n    $fieldErrors = $e->getEntity()->getErrors();\n    $this->addReportItem(ActionReport::ERROR, 'User data validation failed', json_encode($fieldErrors));\n}","preventionTips":["Always read $entity->getErrors() on the thrown ValidationException to identify the offending fields.","Audit LDAP attribute mappings (mail, givenName, sn) so valid values feed passbolt's username/profile fields.","Detect and resolve duplicate emails/usernames between the directory and passbolt before sync.","Validate directory-supplied data against the User entity rules before calling editEntity.","Catch ValidationException per-user so a single invalid account does not abort the entire sync run."],"tags":["validation","directory-sync","ldap","entity-validation"],"backgroundTag":"schema-validation-failed","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"}