yiisoft/yii2 · error · yii\base\InvalidArgumentException
{class} has no attribute named "{name}".
Error message
{class} has no attribute named "{name}". What it means
setAttribute() writes into the model's attribute store only after hasAttribute() confirms the name — meaning it is either already present in _attributes or is a column of the model's table schema. Any other name raises InvalidArgumentException with the class and the offending attribute, stopping typos and writes to columns the schema does not know.
Source
Thrown at framework/db/BaseActiveRecord.php:541
/**
* Sets the named attribute value.
* @param string $name the attribute name
* @param mixed $value the attribute value.
* @throws InvalidArgumentException if the named attribute does not exist.
* @see hasAttribute()
*/
public function setAttribute($name, $value)
{
if ($this->hasAttribute($name)) {
if (
!empty($this->_relationsDependencies[$name])
&& (!array_key_exists($name, $this->_attributes) || $this->_attributes[$name] !== $value)
) {
$this->resetDependentRelations($name);
}
$this->_attributes[$name] = $value;
} else {
throw new InvalidArgumentException(get_class($this) . ' has no attribute named "' . $name . '".');
}
}
/**
* Returns the old attribute values.
* @return array the old attribute values (name-value pairs)
*/
public function getOldAttributes()
{
return $this->_oldAttributes === null ? [] : $this->_oldAttributes;
}
/**
* Sets the old attribute values.
* All existing old attribute values will be discarded.
* @param array|null $values old attribute values to be set.
* If set to `null` this record is considered to be [[isNewRecord|new]].
*/View on GitHub (pinned to 66f00d18a2)
Solutions
- Fix the attribute name to exactly match the table column
- Flush the schema cache after altering the table (Yii::$app->cache->flush(), or disable enableSchemaCache in dev)
- For virtual properties, add a setter (setXyz) instead of using setAttribute
- Guard writes: if ($model->hasAttribute($name)) { $model->setAttribute($name, $value); }
Example fix
// before
$user->setAttribute('emial', 'a@b.c'); // throws: has no attribute "emial"
// after
$user->setAttribute('email', 'a@b.c'); Defensive patterns
Strategy: validation
Validate before calling
if (!$model->hasAttribute($name)) {
throw new InvalidArgumentException(get_class($model) . " has no attribute '{$name}'.");
}
$model->setAttribute($name, $value); Prevention
- Filter mass-assignment input against $model->activeAttributes() or schema column names
- Flush the schema cache after ALTER TABLE during development
- Lint attribute names in tests with real model instances
When it happens
Trigger: $model->setAttribute('emial', $v) with a typo; setting a column added to the table after the schema cache was populated; setting a virtual/computed property that exists only as a getter; mass-assignment loops that feed unvalidated keys.
Common situations: Stale schema cache after ALTER TABLE in development; form or importer data containing extra keys; column renamed in migration but code not updated; copy-pasting attribute names across similar models.
Related errors
- Getting unknown property: {class}::{name}
- Setting unknown property: {class}::{name}
- Calling unknown method: {class}::{name}()
- Primary key of '{$class}' can not be empty.
- "{}" must have a primary key.
AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17).
Data as JSON: /api/errors/ee3d6ffdd5bd15b2.
Report an issue: GitHub.