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
- Normalize every rule to [[attributes], type, ...options] or a Validator instance before passing it
- 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])
- 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
- Build rules only from a tested factory that guarantees the [attributes, type, ...options] shape
- When rules come from config or DB, validate their structure before use
- Never hand-write single-element rule arrays; always include the validator type
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
- Invalid validation rule: a rule must specify both attribute
- Invalid path alias: $alias
- Unsupported configuration type: ' . gettype($type)
- Object configuration must be an array containing a "class" o
- The "id" configuration for the Application is required.
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/ca2ccbd96b1cff99.
Report an issue: GitHub.