{"record":{"id":"ee3d6ffdd5bd15b2","repo":"yiisoft/yii2","slug":"class-has-no-attribute-named-name","errorCode":null,"errorMessage":"{class} has no attribute named \"{name}\".","messagePattern":"(.+?) has no attribute named \"(.+?)\"\\.","errorType":"exception","errorClass":"yii\\base\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"framework/db/BaseActiveRecord.php","lineNumber":541,"sourceCode":"    /**\n     * Sets the named attribute value.\n     * @param string $name the attribute name\n     * @param mixed $value the attribute value.\n     * @throws InvalidArgumentException if the named attribute does not exist.\n     * @see hasAttribute()\n     */\n    public function setAttribute($name, $value)\n    {\n        if ($this->hasAttribute($name)) {\n            if (\n                !empty($this->_relationsDependencies[$name])\n                && (!array_key_exists($name, $this->_attributes) || $this->_attributes[$name] !== $value)\n            ) {\n                $this->resetDependentRelations($name);\n            }\n            $this->_attributes[$name] = $value;\n        } else {\n            throw new InvalidArgumentException(get_class($this) . ' has no attribute named \"' . $name . '\".');\n        }\n    }\n\n    /**\n     * Returns the old attribute values.\n     * @return array the old attribute values (name-value pairs)\n     */\n    public function getOldAttributes()\n    {\n        return $this->_oldAttributes === null ? [] : $this->_oldAttributes;\n    }\n\n    /**\n     * Sets the old attribute values.\n     * All existing old attribute values will be discarded.\n     * @param array|null $values old attribute values to be set.\n     * If set to `null` this record is considered to be [[isNewRecord|new]].\n     */","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/db/BaseActiveRecord.php#L523-L559","documentation":"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.","triggerScenarios":"$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.","commonSituations":"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.","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); }"],"exampleFix":"// before\n$user->setAttribute('emial', 'a@b.c'); // throws: has no attribute \"emial\"\n\n// after\n$user->setAttribute('email', 'a@b.c');","handlingStrategy":"validation","validationCode":"if (!$model->hasAttribute($name)) {\n    throw new InvalidArgumentException(get_class($model) . \" has no attribute '{$name}'.\");\n}\n$model->setAttribute($name, $value);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["active-record","attributes","schema-cache","typo"],"backgroundTag":"unknown-attribute-name","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}