passbolt/passbolt_api · error · FormValidationException

Could not validate the password expiry settings.

Error message

Could not validate the password expiry settings.

What it means

FormValidationException thrown by PasswordExpiryGetSettingsService::get when stored settings value data fails the password expiry settings form validation. The persisted organization settings payload no longer satisfies the form rules, so building the DTO is aborted.

Solutions

  1. Log or inspect $form->getErrors() to identify the failing field.
  2. Re-save the password expiry settings through the API so they are validated and normalized.
  3. Fix the stored value directly: use the documented period format like '90d' (N followed by d/w/m/y).
  4. Check for plugin version drift and run migrations/update the plugin to align validation rules.

Example fix

// before (stored value)
{"automatic_expiry": {"automatic_expiry_period": "90"}}
// after
{"automatic_expiry": {"automatic_expiry_period": "90d"}}
Defensive patterns

Strategy: try-catch

Validate before calling

if (isset($stored['automatic_expiry']['automatic_expiry_period']) && !preg_match('/^\d+[dwmy]$/', $stored['automatic_expiry']['automatic_expiry_period'])) { // resave settings }

Try / catch

try { $dto = $service->get(); } catch (FormValidationException $e) { $errs = $e->getForm()->getErrors(); }

Prevention

When it happens

Trigger: Reading password expiry settings whose stored 'value' array (decoded from organization_settings) fails $form->execute($data) — e.g. invalid automatic_expiry_period format or wrong types.

Common situations: Settings written by an older plugin version or manually edited in the database using keys/period formats the current validation form rejects (e.g. '90' instead of '90d').

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/27c3df8ef88f25e1. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/PasswordExpiry/src/Service/Settings/PasswordExpiryGetSettingsService.php:67

        $passwordExpirySettingsTable = $this->fetchTable('Passbolt/PasswordExpiry.PasswordExpirySettings');

        /** @var \Passbolt\PasswordExpiry\Model\Entity\PasswordExpirySetting|null $passwordExpirySettings */
        $passwordExpirySettings = $passwordExpirySettingsTable->find()->first();

        if (is_null($passwordExpirySettings)) {
            $this->dto = $this->createDTOFromArray([]);

            return $this->dto;
        }

        if (!is_array($passwordExpirySettings->value)) {
            throw new InternalErrorException('The value should be an array');
        }

        $data = $passwordExpirySettings->value;
        $form = $this->getForm();
        if (!$form->execute($data)) {
            throw new FormValidationException(
                __('Could not validate the password expiry settings.'),
                $form
            );
        }
        $this->dto = $this->createDTOFromEntity($passwordExpirySettings, $form);

        return $this->dto;
    }
}

View on GitHub (pinned to 31c1bbc10f)