passbolt/passbolt_api · error · ValidationException

Could not validate permission history data.

Error message

Could not validate permission history data.

What it means

PermissionsHistoryTable::create() throws this ValidationException when the PermissionHistory entity built via buildEntity() fails validation before any save. The supplied permission history data (e.g. permission_id, type, acl_foreign_key) violates the table's rules.

Solutions

  1. Inspect the entity errors included in the ValidationException for the exact failing field.
  2. Supply all required PermissionHistory fields (permission_id, type, acl_foreign_key, etc.) matching the original permission.
  3. Ensure the permission type is one of the valid defined type constants.
  4. If triggered via EntitiesHistory save with associated PermissionsHistory, fix the nested association payload.

Example fix

// before
$this->PermissionsHistory->create(['permission_id' => $permissionId]);
// after
$this->PermissionsHistory->create([
    'permission_id' => $permissionId,
    'type' => $permission->type,
    'aco' => $permission->aco,
    'aco_foreign_key' => $permission->aco_foreign_key,
    'aro' => $permission->aro,
    'aro_foreign_key' => $permission->aro_foreign_key,
]);
Defensive patterns

Strategy: validation

Validate before calling

function validatePermissionHistoryData(array $data): bool { return !empty($data['permission_id']) && isset($data['type']) && is_int($data['type']) && !empty($data['acl_foreign_key']); }

Type guard

function isPermissionHistoryPayload(mixed $data): bool { return is_array($data) && isset($data['permission_id'], $data['type']); }

Try / catch

try { $permissionsHistoryTable->create($data); } catch (ValidationException $e) { $errors = $e->getEntity()->getErrors(); // correct the fields listed in $errors before retry
}

Prevention

When it happens

Trigger: create() called with data missing required columns or with invalid values: empty permission_id, an out-of-range permission type integer, empty/invalid acl_foreign_key, or an invalid data blob format.

Common situations: Logging a permission change where the original permission row was incomplete; permission type constants changed between versions so the stored type no longer validates; passing an entity instead of an array to create(); missing fields not covered by the $defaultData merge.

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/c4a75ecab4135165. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/Log/src/Model/Table/PermissionsHistoryTable.php:200

                'type' => true,
            ],
        ]);
    }

    /**
     * Create a new permissions_history.
     *
     * @param array $data the data
     * @return \Passbolt\Log\Model\Entity\PermissionHistory
     * @throws \App\Error\Exception\ValidationException
     * @throws \Cake\Http\Exception\InternalErrorException
     */
    public function create(array $data): PermissionHistory
    {
        // Check validation rules.
        $log = $this->buildEntity($data);
        if ($log->getErrors()) {
            throw new ValidationException(__('Could not validate permission history data.', true), $log, $this);
        }

        $permissionHistory = $this->save($log);

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

        // Check for errors while saving.
        if (!$permissionHistory) {
            throw new InternalErrorException('Could not save permission history.');
        }

        return $permissionHistory;
    }
}

View on GitHub (pinned to 31c1bbc10f)