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
- Check the errors array on the exception entity to see which field failed validation
- Send only the exact allowed status values 'approved' or 'rejected' in the request payload
- Verify the request id exists and has not already been approved/rejected
- 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
- Always send the exact lowercase enum values 'approved'/'rejected'
- Check the request is still pending before updating
- Keep payloads minimal: only status field, let server set modified_by
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
- Could not save the account recovery private key.
- Could not save the account recovery setting.
- Could not validate key revocation.
- Could not validate password data.
- Could not validate password data.
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)