phalcon/cphalcon · error · Phalcon\Filter\Validation\Exceptions\NoValidatorsInComposite

{className} does not have any validator added

Error message

{className} does not have any validator added

What it means

Composite validators (anything using ValidatorCompositeTrait, e.g. extending Phalcon\Filter\Validation\AbstractValidatorComposite) run an inner list of validators; validate() refuses to run on an empty list and throws Phalcon\Filter\Validation\Exceptions\NoValidatorsInComposite naming the class (phalcon/Filter/Validation/Traits/ValidatorCompositeTrait.zep:42). The trait property defaults to null, so a subclass that never populates it fails on first use.

Source

Thrown at phalcon/Filter/Validation/Traits/ValidatorCompositeTrait.zep:42

    protected validators = null;

    /**
     * @return array
     */
    public function getValidators() -> array
    {
        return (array) this->validators;
    }

    /**
     * Executes the validation
     */
    public function validate(<\Phalcon\Filter\Validation> validation, var field) -> bool
    {
        var validator;

        if unlikely empty this->getValidators() {
            throw new \Phalcon\Filter\Validation\Exceptions\NoValidatorsInComposite(
                get_class(this)
            );
        }

        for validator in this->getValidators() {
            if validator->validate(validation, field) === false {
                return false;
            }
        }

        return true;
    }
}

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Populate the list in the composite's constructor (or init): $this->validators = [new PresenceOf([...]), new Email([...])];
  2. Add a unit test asserting count($composite->getValidators()) > 0 for every composite you define.
  3. Catch NoValidatorsInComposite in your validation harness to fail fast with the class name when wiring is missing.

Example fix

// before
class MyComposite extends AbstractValidatorComposite
{
    // validators never set -> NoValidatorsInComposite on validate()
}

// after
class MyComposite extends AbstractValidatorComposite
{
    public function __construct(array $options = [])
    {
        parent::__construct($options);
        $this->validators = [
            new PresenceOf(['message' => 'Value required']),
            new Email(['message' => 'Invalid e-mail']),
        ];
    }
}
Defensive patterns

Strategy: validation

Validate before calling

$composite = new MyComposite();
if ($composite->getValidators() === []) {
    throw new LogicException(get_class($composite) . ' has no validators registered');
}
$validation->add('field', $composite);

Try / catch

use Phalcon\Filter\Validation\Exceptions\NoValidatorsInComposite;

try {
    $validation->validate($_POST);
} catch (NoValidatorsInComposite $e) {
    // developer error, not user input error: fix the composite wiring
    $logger->critical($e->getMessage());
    throw $e;
}

Prevention

When it happens

Trigger: A custom composite validator whose constructor/init never assigns $this->validators (or assigns under a typo'd/renamed property), then $validation->add('field', $composite) and $validation->validate() invokes it.

Common situations: Copy-pasting a composite class and dropping the constructor wiring; renaming the property during a refactor; validators registered conditionally so a branch skips all adds; upgrading code that relied on an older base class that populated validators differently.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/4ca1a4cebc3f6c41. Report an issue: GitHub.