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 PasswordExpirySetSettingsService::createOrUpdate when the submitted settings payload fails the password expiry settings form validation ($form->execute returns false). Nothing is persisted when this fires.

Solutions

  1. Inspect the FormValidationException errors (form->getErrors()) to identify failing fields.
  2. Send the full expected payload with automatic_expiry containing valid boolean flags and a period in the accepted format (e.g. '90d').
  3. Validate the payload client-side before posting.
  4. Check the API docs/plugin version for the exact accepted schema.

Example fix

// before
{"automatic_expiry": {"automatic_expiry_on_delete_on_expired": "yes", "automatic_expiry_period": "3 months"}}
// after
{"automatic_expiry": {"automatic_expiry_on_delete_on_expired": true, "automatic_expiry_period": "90d"}}
Defensive patterns

Strategy: validation

Validate before calling

$valid = preg_match('/^\d+[dwmy]$/', $data['automatic_expiry']['automatic_expiry_period'] ?? '') && is_bool($data['automatic_expiry']['automatic_expiry_on_delete_on_expired'] ?? null);

Try / catch

try { $dto = $service->createOrUpdate($uac, $data); } catch (FormValidationException $e) { $errs = $e->getForm()->getErrors(); }

Prevention

When it happens

Trigger: POST/PUT to /password-expiry/settings with a payload missing required keys, containing unknown keys, or with an invalid automatic_expiry_period / automatic_expiry_on_delete_on_expired value.

Common situations: Admin UI/API integrations sending period values like '3 months' or '90' instead of the required compact format ('90d'), or omitting the automatic_expiry object entirely.

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/44af9957d75e1a48. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltCe/PasswordExpiry/src/Service/Settings/PasswordExpirySetSettingsService.php:43

class PasswordExpirySetSettingsService extends PasswordExpirySettingsAbstractService implements PasswordExpirySetSettingsServiceInterface // phpcs:ignore
{
    use EventDispatcherTrait;

    /**
     * Event name. Fired after password expiry settings has been saved.
     *
     * @var string
     */
    public const EVENT_SETTINGS_UPDATED = 'Service.PasswordExpirySetSettingsService.updated';

    /**
     * @inheritDoc
     */
    final public function createOrUpdate(ExtendedUserAccessControl $uac, array $data): PasswordExpirySettingsDto
    {
        $form = $this->getForm();
        if (!$form->execute($data)) {
            throw new FormValidationException(__('Could not validate the password expiry settings.'), $form);
        }

        /** @var \Passbolt\PasswordExpiry\Model\Table\PasswordExpirySettingsTable $passwordExpirySettingsTable */
        $passwordExpirySettingsTable = $this->fetchTable('Passbolt/PasswordExpiry.PasswordExpirySettings');

        /** @var \Passbolt\PasswordExpiry\Model\Entity\PasswordExpirySetting $passwordExpirySetting */
        $passwordExpirySetting = $passwordExpirySettingsTable->createOrUpdateSetting(
            $passwordExpirySettingsTable->getProperty(),
            $this->createDTOFromArray($form->getData())->getValue(),
            $uac
        );

        /** Dispatch settings updated event. */
        $this->dispatchEvent(self::EVENT_SETTINGS_UPDATED, compact('uac'), $passwordExpirySetting);

        return $this->createDTOFromEntity($passwordExpirySetting, $form);
    }
}

View on GitHub (pinned to 31c1bbc10f)