passbolt/passbolt_api · error · ValidationException

Could not validate entity history data.

Error message

Could not validate entity history data.

What it means

EntitiesHistoryTable::create() throws this ValidationException when the entity history entity built via buildEntity() fails validation rules before saving. The supplied data (e.g. entity type, foreign model, foreign key, or crud flag) violates the table's ruleset.

Solutions

  1. Inspect the entity errors attached to the ValidationException to identify the failing field.
  2. Ensure required fields are present: foreign_model, foreign_key, crud, and any per-type fields.
  3. Verify the entity type/foreign model string matches the expected constants exactly.
  4. If the data is legitimate, adjust the validation ruleset rather than bypassing validation.

Example fix

// before
$this->EntitiesHistory->create([
    'foreign_model' => 'Permission',
    'foreign_key' => $permissionId,
]);
// after
$this->EntitiesHistory->create([
    'foreign_model' => 'Permission',
    'foreign_key' => $permissionId,
    'crud' => 'u',
]);
Defensive patterns

Strategy: validation

Validate before calling

function validateEntityHistoryData(array $data): bool { return !empty($data['foreign_model']) && !empty($data['foreign_key']) && in_array($data['crud'] ?? null, ['c','u','d'], true); }

Type guard

function isEntityHistoryPayload(mixed $data): bool { return is_array($data) && isset($data['foreign_model'], $data['foreign_key'], $data['crud']); }

Try / catch

try { $eh = $entitiesHistoryTable->create($data); } catch (ValidationException $e) { $errors = $e->getEntity()->getErrors(); // fix payload before retrying
}

Prevention

When it happens

Trigger: create() called with missing/invalid fields: unknown entity type (foreign_model), empty foreign_key, invalid crud value, or data merged over $defaultData that still lacks required columns.

Common situations: Plugins logging entity changes with a foreign_model not in the allowed list; passing an integer foreign key where a UUID string is expected; forgetting the 'crud' field when merging custom data over defaults; after a schema change that made a formerly-optional field required.

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

Appendix: source

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

     * Create a new entity_history.
     *
     * @param array $data the data: foreign_key and foreign_model
     * @param \App\Utility\UserAction $userAction userAction object
     * @return \Passbolt\Log\Model\Entity\EntityHistory
     * @throws \App\Error\Exception\ValidationException
     * @throws \Cake\Http\Exception\InternalErrorException
     */
    public function create(array $data, UserAction $userAction): EntityHistory
    {
        $defaultData = [
            'action_log_id' => $userAction->getUserActionId(),
        ];
        $data = array_merge($defaultData, $data);

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

        $entityHistory = $this->save($log, ['associated' => ['PermissionsHistory']]);

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

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

        return $entityHistory;
    }
}

View on GitHub (pinned to 31c1bbc10f)