yiisoft/yii2 · error · InvalidConfigException

Invalid validation rule: a rule must specify both attribute

Error message

Invalid validation rule: a rule must specify both attribute names and validator type.

What it means

DynamicModel::validateData($data, $rules) accepts each rule either as a ready yii\validators\Validator instance or as an array where element 0 is the attribute list and element 1 the validator type (further elements are options). Any rule that is not an instance and lacks one of those two slots throws InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.') before validation runs.

Source

Thrown at framework/base/DynamicModel.php:234

     * @return static the model instance that contains the data being validated.
     * @throws InvalidConfigException if a validation rule is not specified correctly.
     */
    public static function validateData(array $data, $rules = [])
    {
        /** @var static $model */
        $model = new static($data);
        if (!empty($rules)) {
            $validators = $model->getValidators();
            foreach ($rules as $rule) {
                if ($rule instanceof Validator) {
                    $validators->append($rule);
                    $model->defineAttributesByValidator($rule);
                } elseif (is_array($rule) && isset($rule[0], $rule[1])) { // attributes, validator type
                    $validator = Validator::createValidator($rule[1], $model, (array)$rule[0], array_slice($rule, 2));
                    $validators->append($validator);
                    $model->defineAttributesByValidator($validator);
                } else {
                    throw new InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.');
                }
            }
        }

        $model->validate();

        return $model;
    }

    /**
     * Define the attributes that applies to the specified Validator.
     * @param Validator $validator the validator whose attributes are to be defined.
     */
    private function defineAttributesByValidator($validator)
    {
        foreach ($validator->getAttributeNames() as $attribute) {
            if (!$this->hasAttribute($attribute)) {
                $this->defineAttribute($attribute);

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Normalize every rule to [[attributes], type, ...options] or a Validator instance before passing it
  2. Validate the rules array before calling validateData: each element must be a Validator or an array with both isset($rule[0]) and isset($rule[1])
  3. Unit-test the rules builder so malformed entries fail in CI instead of at request time

Example fix

// before - rule has attributes but no validator type
$model = \yii\base\DynamicModel::validateData($data, [
    ['email'],
]);

// after
$model = \yii\base\DynamicModel::validateData($data, [
    [['email'], 'email'],
]);
Defensive patterns

Strategy: validation

Validate before calling

use yii\validators\Validator;
foreach ($rules as $rule) {
    if (!$rule instanceof Validator && !(is_array($rule) && isset($rule[0], $rule[1]))) {
        throw new \InvalidArgumentException('Malformed validation rule: ' . var_export($rule, true));
    }
}
$model = \yii\base\DynamicModel::validateData($data, $rules);

Try / catch

try {
    $model = \yii\base\DynamicModel::validateData($data, $rules);
} catch (\yii\base\InvalidConfigException $e) {
    // message: Invalid validation rule: ...
    Yii::error('Bad rules array: ' . print_r($rules, true));
    throw $e;
}

Prevention

When it happens

Trigger: A rule like ['email'] (attributes but no type) or a bare string 'required' instead of ['field', 'required']; rule arrays assembled dynamically where merges, shifts, or conditionals left a slot empty; copying only one column of a model's rules() table into a DynamicModel call.

Common situations: Ad-hoc validation of settings forms or API payloads; rules generated from configuration or database values; partial copy-paste of rule fragments.

Related errors


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/ca2ccbd96b1cff99. Report an issue: GitHub.