passbolt/passbolt_api · error · App\Error\Exception\ValidationException

Could not validate group data.

Error message

Could not validate group data.

What it means

GroupsTable::create() merges default data, builds the group entity via buildEntity(), and throws ValidationException('Could not validate group data.') if the entity already carries errors before saving. The entity is attached so callers can read the detailed errors.

Solutions

  1. Catch ValidationException and inspect $e->getEntity()->getErrors() for the exact field failures.
  2. Ensure the payload includes a valid name and correctly shaped users data.
  3. Validate against the groups validation rules before calling create().
  4. Use the API schema documentation for the required group creation fields.

Example fix

// before
$this->Groups->create($data, ['userId' => $uId]); // throws on bad name
// after
$data['name'] = trim($data['name'] ?? '');
if ($data['name'] === '') { throw new BadRequestException('A group name is required.'); }
$this->Groups->create($data, ['userId' => $uId]);
Defensive patterns

Strategy: validation

Validate before calling

$data['name'] = trim($data['name'] ?? '');
if ($data['name'] === '') { throw new BadRequestException('Group name is required.'); }
if (!isset($data['users']) || !is_array($data['users'])) { throw new BadRequestException('users must be an array.'); }

Type guard

function isValidGroupPayload(array $data): bool {
  return isset($data['name']) && is_string($data['name']) && trim($data['name']) !== ''
    && (!isset($data['users']) || is_array($data['users']));
}

Try / catch

try { $group = $this->Groups->create($data, ['userId' => $uId]); }
catch (ValidationException $e) {
  $fieldErrors = $e->getEntity()->getErrors();
  throw new BadRequestException(json_encode($fieldErrors));
}

Prevention

When it happens

Trigger: Calling GroupsTable::create($data) where the built group entity fails validation — e.g. missing/invalid group name, invalid users data structure, or rule violations applied in buildEntity (beforeSave rules).

Common situations: API payloads omitting the name field, duplicate group names if uniqueness rules apply, malformed 'users' association arrays, or passing SecretsGroupsChanges data in the wrong shape.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at src/Model/Table/GroupsTable.php:253

     * @param \App\Utility\UserAccessControl $control access control details
     * @return \App\Model\Entity\Group
     * @throws \App\Error\Exception\ValidationException
     * @throws \Cake\Http\Exception\InternalErrorException
     */
    public function create(array $data, UserAccessControl $control): Group
    {
        // Manage defaults.
        $defaults = [
            'created_by' => $control->getId(),
            'modified_by' => $control->getId(),
            'deleted' => false,
        ];
        $data = array_merge($defaults, $data);

        // Check validation rules.
        $group = $this->buildEntity($data);
        if ($group->getErrors()) {
            throw new ValidationException(__('Could not validate group data.'), $group, $this);
        }

        $groupSaved = $this->save($group);

        // Check for validation errors. (associated models too).
        if ($group->getErrors()) {
            throw new ValidationException(__('Could not validate group data.'), $group, $this);
        }

        // Check for errors while saving.
        if (!$groupSaved) {
            throw new InternalErrorException('Could not save the group, try again later.');
        }

        // Dispatch event.
        $eventData = ['group' => $groupSaved, 'requester' => $control];
        $event = new Event(static::GROUP_CREATE_SUCCESS_EVENT_NAME, $this, $eventData);
        $this->getEventManager()->dispatch($event);

View on GitHub (pinned to 31c1bbc10f)