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

  1. Check nested errors under account_recovery_user_setting for the failing entry index
  2. Re-encrypt the private key passwords with the current organization public key fetched from the server
  3. Ensure each password is properly base64-encoded encrypted data per the API schema
  4. 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

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


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)