laravel/framework · error · MassAssignmentException

Add fillable property

Error message

Add fillable property [%s] to allow mass assignment on [%s].

What it means

Thrown by the tail of fill() when the number of keys passed does not match the keys fillableFromArray() returned, AND Model::preventsSilentlyDiscardingAttributes() is enabled. Unlike the per-key check, this fires for keys that were never even considered (entirely outside the fillable set) and reports all of them at once. It only fires in strict mode; with default settings those keys are silently ignored.

Solutions

  1. Add every reported key to the model's $fillable array.
  2. Strip non-fillable keys from the input before calling fill (e.g. only($fillableKeys)).
  3. Use forceFill() when you intentionally want to bypass the guard for those keys.
  4. If the discard is intentional, disable preventSilentlyDiscardingAttributes() for that flow.

Example fix

// before
Model::preventSilentlyDiscardingAttributes();
$user->fill(['name' => 'A', 'legacy_col' => 1]); // 'legacy_col' not fillable

// after - whitelist or strip
$user->fill(collect(request()->all())->only((new User)->getFillable())->toArray());
Defensive patterns

Strategy: validation

Validate before calling

// Strip anything not fillable before fill() so strict mode never trips
$fillable = (new $modelClass)->getFillable();
$model->fill(collect($input)->only($fillable)->toArray());

Type guard

function allKeysFillable(\Illuminate\Database\Eloquent\Model $model, array $input): bool {
    return empty(array_diff(array_keys($input), $fillable = $model->getFillable()));
}

Try / catch

try {
    $model->fill($input);
} catch (\Illuminate\Database\Eloquent\MassAssignmentException $e) {
    if (str_contains($e->getMessage(), 'Add fillable property')) {
        // parse keys from message, report; or fall back to only()
        $model->fill(collect($input)->only($model->getFillable())->toArray());
    } else { throw $e; }
}

Prevention

When it happens

Trigger: Model::preventSilentlyDiscardingAttributes() has been called (typically in AppServiceProvider boot), then Model::fill([...]) / ::create([...]) is called with one or more keys that are not in $fillable.

Common situations: Strict mode turned on across the app to surface dropped fields; a FormRequest returning extra keys the model does not whitelist; renaming a DB column but not the request payload; hidden/extra input fields in tests.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/9bc7253a285b8365. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Database/Eloquent/Model.php:708

                if (isset(static::$discardedAttributeViolationCallback)) {
                    call_user_func(static::$discardedAttributeViolationCallback, $this, [$key]);
                } else {
                    throw new MassAssignmentException(sprintf(
                        'Add [%s] to fillable property to allow mass assignment on [%s].',
                        $key, get_class($this)
                    ));
                }
            }
        }

        if (count($attributes) !== count($fillable) &&
            static::preventsSilentlyDiscardingAttributes()) {
            $keys = array_diff(array_keys($attributes), array_keys($fillable));

            if (isset(static::$discardedAttributeViolationCallback)) {
                call_user_func(static::$discardedAttributeViolationCallback, $this, $keys);
            } else {
                throw new MassAssignmentException(sprintf(
                    'Add fillable property [%s] to allow mass assignment on [%s].',
                    implode(', ', $keys),
                    get_class($this)
                ));
            }
        }

        return $this;
    }

    /**
     * Fill the model with an array of attributes. Force mass assignment.
     *
     * @param  array<string, mixed>  $attributes
     * @return $this
     */
    public function forceFill(array $attributes)
    {

View on GitHub (pinned to e0f6eb3518)