passbolt/passbolt_api · error · ValidationException

The account request is invalid.

Error message

The account request is invalid.

What it means

Thrown by AccountRecoveryRequestsTable::updateStatusAndValidateEntity when the account recovery request entity fails CakePHP entity validation after being patched with a new status and modified_by. It signals that the submitted status transition (e.g. approving/rejecting a recovery request by an administrator) violates the table's validation rules. The entity with its errors is attached to the exception.

Solutions

  1. Check the errors array on the exception entity to see which field failed validation
  2. Send only the exact allowed status values 'approved' or 'rejected' in the request payload
  3. Verify the request id exists and has not already been approved/rejected
  4. Ensure the account recovery organization policy is enabled before attempting status updates

Example fix

// before
PATCH /account-recovery/requests/<uuid> {"status": "approve"}
// after
PATCH /account-recovery/requests/<uuid> {"status": "approved"}
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED = ['approved', 'rejected'];
if (!ALLOWED.includes(payload.status)) {
  throw new Error(`status must be one of ${ALLOWED.join(', ')}`);
}

Type guard

function isValidRequestStatus(s) {
  return typeof s === 'string' && ['approved', 'rejected'].includes(s);
}

Try / catch

try {
  await api.updateRequestStatus(id, status);
} catch (e) {
  if (e.body?.errors) console.error(e.body.errors); // inspect field errors
}

Prevention

When it happens

Trigger: Calling the account recovery request status-update service (POST /account-recovery/requests/<id>.json for admins) with a status value not in the allowed list, an unknown request id producing rule violations, or patching an entity that already has errors from a prior state check.

Common situations: Admin UI or API client sends a typo'd status string (e.g. 'approve' instead of 'approved'); attempting to update a request that is already in a terminal state; automated scripts replaying stale requests after the organization policy changed.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/AccountRecovery/src/Model/Table/AccountRecoveryRequestsTable.php:458

     * @return \Passbolt\AccountRecovery\Model\Entity\AccountRecoveryRequest
     */
    public function updateStatusAndValidateEntity(
        UserAccessControl $uac,
        AccountRecoveryRequest $requestEntity,
        string $responseStatus
    ): AccountRecoveryRequest {
        /** @var \Passbolt\AccountRecovery\Model\Entity\AccountRecoveryRequest $requestEntity */
        $requestEntity = $this->patchEntity($requestEntity, [
            'status' => $this->getRequestStatusFromResponse($responseStatus),
            'modified_by' => $uac->getId(),
        ], ['accessibleFields' => [
            'status' => true,
            'modified_by' => true,
        ]]);

        if ($requestEntity->getErrors()) {
            $msg = __('The account request is invalid.');
            throw new ValidationException($msg, $requestEntity, $this);
        }

        return $requestEntity;
    }

    /**
     * Return new request status based on response status
     *
     * @param string $status response status
     * @return string mapped request status
     */
    protected function getRequestStatusFromResponse(string $status): string
    {
        if ($status === AccountRecoveryResponse::STATUS_REJECTED) {
            return AccountRecoveryRequest::ACCOUNT_RECOVERY_REQUEST_REJECTED;
        }
        if ($status === AccountRecoveryResponse::STATUS_APPROVED) {
            return AccountRecoveryRequest::ACCOUNT_RECOVERY_REQUEST_APPROVED;

View on GitHub (pinned to 31c1bbc10f)