passbolt/passbolt_api · error · FormValidationException

The self registration data could not be validated.

Error message

The self registration data could not be validated.

What it means

Thrown by SelfRegistrationEmailDomainsDryRunService::canGuestSelfRegister when the dry-run payload fails SelfRegistrationEmailDomainsDryRunForm validation. FormValidationException carries the form with per-field errors. The payload must be shaped so the email-domains check can evaluate it.

Solutions

  1. Read the form errors attached to the FormValidationException for exact field failures
  2. Include a valid 'email' key in the dry-run payload
  3. Ensure the payload is an associative array (JSON object) and not nested incorrectly
  4. Compare against the fields expected by SelfRegistrationEmailDomainsDryRunForm

Example fix

// before
curl -d '{"username":"ada@example.com"}' /self-registration/dry-run
// after
curl -d '{"email":"ada@example.com"}' /self-registration/dry-run
Defensive patterns

Strategy: validation

Validate before calling

const payload = { email: 'ada@example.com' };
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(payload.email ?? '')) {
  throw new Error('email key is required and must be a valid address');
}

Type guard

const isEmailPayload = (d) => typeof d === 'object' && d !== null && typeof d.email === 'string' && d.email.includes('@');

Try / catch

try {
    await api.post('/self-registration/dry-run', payload);
} catch (e) {
    if (e.status === 400 && e.errors) { // FormValidationException payload
        renderFieldErrors(e.errors);
    }
}

Prevention

When it happens

Trigger: Dry-run request missing the required 'email' field, containing a non-email string, or including unexpected/invalid keys rejected by the form.

Common situations: Clients omitting the email key; sending username only; empty payload fields; API version mismatch where the expected key changed.

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

Appendix: source

Thrown at plugins/PassboltCe/SelfRegistration/src/Service/DryRun/SelfRegistrationEmailDomainsDryRunService.php:39

use Cake\Http\Exception\ForbiddenException;
use Cake\ORM\TableRegistry;
use Passbolt\SelfRegistration\Form\DryRun\SelfRegistrationEmailDomainsDryRunForm;

class SelfRegistrationEmailDomainsDryRunService extends SelfRegistrationAbstractDryRunService
{
    /**
     * @param array $data data in the payload
     * @return bool
     * @throws \Cake\Http\Exception\ForbiddenException if no allowed domains are found in the settings.
     * @throws \Cake\Http\Exception\ForbiddenException if the email is already registered.
     * @throws \App\Error\Exception\FormValidationException if no valid email is provided in the payload.
     * @throws \Cake\Http\Exception\InternalErrorException if the data in the DB is invalid.
     */
    public function canGuestSelfRegister(array $data): bool
    {
        $form = new SelfRegistrationEmailDomainsDryRunForm();
        if (!$form->execute($data)) {
            throw new FormValidationException(
                __('The self registration data could not be validated.'),
                $form
            );
        }

        $allowedDomains = $this->getAllowedDomainsInSettings();

        $email = $form->getData('email');
        $this->checkEmailDomainIsAllowed($email, $allowedDomains);
        $this->checkEmailNotPreviouslyRegistered($email);

        return true;
    }

    /**
     * @return array
     * @throws \Cake\Http\Exception\ForbiddenException if no allowed domains are found in the settings.
     * @throws \Cake\Http\Exception\InternalErrorException if the settings in DB are not valid.

View on GitHub (pinned to 31c1bbc10f)