{"id":"70836770fb6174ed","repo":"laravel/framework","slug":"add-s-to-fillable-property-to-allow-mass-assign","errorCode":null,"errorMessage":"Add [%s] to fillable property to allow mass assignment on [%s].","messagePattern":"Add \\[(.+?)\\] to fillable property to allow mass assignment on \\[(.+?)\\]\\.","errorType":"exception","errorClass":"MassAssignmentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Eloquent/Model.php","lineNumber":691,"sourceCode":"     * @throws \\Illuminate\\Database\\Eloquent\\MassAssignmentException\n     */\n    public function fill(array $attributes)\n    {\n        $totallyGuarded = $this->totallyGuarded();\n\n        $fillable = $this->fillableFromArray($attributes);\n\n        foreach ($fillable as $key => $value) {\n            // The developers may choose to place some attributes in the \"fillable\" array\n            // which means only those attributes may be set through mass assignment to\n            // the model, and all others will just get ignored for security reasons.\n            if ($this->isFillable($key)) {\n                $this->setAttribute($key, $value);\n            } elseif ($totallyGuarded || static::preventsSilentlyDiscardingAttributes()) {\n                if (isset(static::$discardedAttributeViolationCallback)) {\n                    call_user_func(static::$discardedAttributeViolationCallback, $this, [$key]);\n                } else {\n                    throw new MassAssignmentException(sprintf(\n                        'Add [%s] to fillable property to allow mass assignment on [%s].',\n                        $key, get_class($this)\n                    ));\n                }\n            }\n        }\n\n        if (count($attributes) !== count($fillable) &&\n            static::preventsSilentlyDiscardingAttributes()) {\n            $keys = array_diff(array_keys($attributes), array_keys($fillable));\n\n            if (isset(static::$discardedAttributeViolationCallback)) {\n                call_user_func(static::$discardedAttributeViolationCallback, $this, $keys);\n            } else {\n                throw new MassAssignmentException(sprintf(\n                    'Add fillable property [%s] to allow mass assignment on [%s].',\n                    implode(', ', $keys),\n                    get_class($this)","sourceCodeStart":673,"sourceCodeEnd":709,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Database/Eloquent/Model.php#L673-L709","documentation":"Thrown by Model::fill() when mass-assigning an attribute that is not in $fillable (and not in $guarded allow-list), and the model is either totally guarded ($guarded=['*'] with empty fillable) or the app has Model::preventSilentlyDiscardingAttributes() enabled. The per-key form fires inside the loop for each offending attribute; the message names the specific key and class.","triggerScenarios":"new User(['role' => 'admin']) or User::create(['role' => 'admin']) where 'role' is not in the User::$fillable array and the model is totally guarded or discarding protection is on.","commonSituations":"Adding a new column/attribute and forgetting to add it to $fillable; using guarded-only models; enabling preventSilentlyDiscardingAttributes() in tests/non-prod which turns previously-silent discards into exceptions.","solutions":["Add the attribute to the model's $fillable array (protected $fillable = ['...', 'role'];).","Assign the attribute directly ($user->role = 'admin'; $user->save()) if it should not be mass-assignable.","Use forceFill(['role' => 'admin']) when you intentionally bypass guard checks.","Audit $guarded and ensure the attribute is not in the guard list, or switch from guarded to explicit fillable."],"exampleFix":"// before\nclass User extends Model {\n    protected $fillable = ['name', 'email'];\n}\nUser::create(['name' => 'x', 'role' => 'admin']); // throws\n\n// after\nclass User extends Model {\n    protected $fillable = ['name', 'email', 'role'];\n}","handlingStrategy":"validation","validationCode":"$fillable = (new $modelClass)->getFillable();\n$unknown = array_diff(array_keys($input), $fillable);\nif ($unknown) {\n    throw new \\InvalidArgumentException('Unknown mass-assignable keys: '.implode(',', $unknown));\n}\n$modelClass::create($input);","typeGuard":"function isMassAssignable($model, string $key): bool {\n    return in_array($key, $model->getFillable(), true) || $model->isGuardableColumn($key) && ! $model->isGuarded($key);\n}","tryCatchPattern":null,"preventionTips":["Maintain $fillable explicitly and review it when adding columns.","Use $request->only([...]) to restrict input keys at the boundary.","Enable preventSilentlyDiscardingAttributes() in tests to catch missing fillable entries early."],"tags":["eloquent","mass-assignment","security","fillable"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}