passbolt/passbolt_api · error · CustomValidationException
$exception->getMessage() (dynamic, from wrapped…
Error message
$exception->getMessage() (dynamic, from wrapped CustomValidationException)
What it means
buildPasswordEntitiesFromDataOrFail() wraps a CustomValidationException coming from AccountRecoveryPrivateKeyPasswordsValidationService and re-throws it with the original message but errors re-nested under 'account_recovery_user_setting' for consistent response shape. The message is dynamic from the wrapped exception.
Solutions
- Check nested errors under account_recovery_user_setting for the failing entry index
- Re-encrypt the private key passwords with the current organization public key fetched from the server
- Ensure each password is properly base64-encoded encrypted data per the API schema
- Refresh the org policy cache so the client uses the latest organization public key
Example fix
// before
encryptWith(oldOrgPublicKey, password)
// after
const {armoredKey} = await orgPolicyGetService.getOrFail();
encryptWith(armoredKey, password) Defensive patterns
Strategy: try-catch
Validate before calling
const {armored_key} = await getOrgPolicy(); // ensure passwords are encrypted to this key before submitting Type guard
const areEncryptedPasswords = (arr) => Array.isArray(arr) && arr.every(p => typeof p === 'string' && /^[A-Za-z0-9+/=]+$/.test(p));
Try / catch
try { await setSettings(data); } catch (e) { if (e.body?.account_recovery_user_setting) showErrors(e.body.account_recovery_user_setting); } Prevention
- Encrypt key passwords with the current organization public key
- Refetch org policy when keys are rotated
- Base64-encode encrypted payloads exactly per schema
When it happens
Trigger: Key password entries failing validation: not a string, not valid base64/encrypted payload, failing to decrypt against the organization public key, or wrong structure in account_recovery_private_key_passwords.
Common situations: Client encrypting key passwords with the wrong recipient key or an outdated organization public key; payloads built for an older schema; corrupted base64 from encoding issues.
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
- The OpenPGP key can not be used to encrypt.
- Could not save the account recovery private key.
- Could not save the account recovery setting.
- Could not validate key revocation.
- Could not validate metadata key data.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/62405d5267c3e782.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php:249
}
return $privateKeyEntity;
}
/**
* @return array<\Passbolt\AccountRecovery\Model\Entity\AccountRecoveryPrivateKeyPassword> array of AccountRecoveryPrivateKeyPasswords
*/
public function buildPasswordEntitiesFromDataOrFail(): array
{
$passwordsData = $this->data['account_recovery_private_key']['account_recovery_private_key_passwords'] ?? [];
try {
$service = new AccountRecoveryPrivateKeyPasswordsValidationService();
$publicKey = $this->organizationPolicy->account_recovery_organization_public_key->armored_key;
return $service->buildPasswordEntitiesFromDataOrFail($this->uac, $passwordsData, $publicKey);
} catch (CustomValidationException $exception) {
// re-wrap errors under parent object
throw new CustomValidationException($exception->getMessage(), [
'account_recovery_user_setting' => $exception->getErrors(),
]);
}
}
/**
* @return bool true if the account_recovery_private_key data is set
*/
protected function isPrivateKeyProvided(): bool
{
return isset($this->data['account_recovery_private_key']);
}
/**
* @return bool true if the account_recovery_private_key.account_recovery_private_key_passwords data is set
*/
protected function arePasswordsProvided(): bool
{View on GitHub (pinned to 31c1bbc10f)