laravel/framework · error · LogicException

Cannot use saveOrIgnore on an existing model.

Error message

Cannot use saveOrIgnore on an existing model.

What it means

saveOrIgnore() is designed only for INSERTs of new models using INSERT ... ON CONFLICT DO NOTHING (or equivalent). When called on a model whose $exists flag is true (already loaded from the DB or previously saved), it throws because the operation is undefined for existing rows - there is no insert to ignore a unique conflict on. Use save()/update() for existing models.

Solutions

  1. For inserts of new records, use a fresh model: $m = new Model; $m->fill(...); $m->saveOrIgnore();.
  2. For existing records, call save() or update() instead of saveOrIgnore().
  3. If you replicated a model, the copy already has exists=false; otherwise unset it, but prefer new instances.
  4. For upsert behavior on existing rows use upsert() / insertOrIgnore() at the query level.

Example fix

// before
$user = User::find($id);
$user->saveOrIgnore(); // throws: $exists is true

// after
$user->save(); // update the existing row
// or for a fresh insert
(new User(['name' => $x]))->saveOrIgnore();
Defensive patterns

Strategy: type-guard

Validate before calling

if ($model->exists) {
    throw new \LogicException('Use save()/update() for existing models; saveOrIgnore is insert-only.');
}
$model->saveOrIgnore();

Type guard

function isNewModel(\Illuminate\Database\Eloquent\Model $m): bool {
    return ! $m->exists;
}

Prevention

When it happens

Trigger: Calling $model->saveOrIgnore() after $model was fetched with find()/first()/get(), or after a prior save() that set $exists=true. Also after replicating a model without unsetting exists.

Common situations: Re-using a hydrated model instance to do an 'insert if not exists' idempotently; a bulk import loop that re-saves existing rows; replicating then saveOrIgnore without first marking the copy as new.

Related errors


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

Appendix: source

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

        // we need to happen after a model gets successfully saved right here.
        if ($saved) {
            $this->finishSave($options);
        }

        return $saved;
    }

    /**
     * Save the model to the database, ignoring specific unique constraint conflicts.
     *
     * @param  array  $options
     * @param  array|string|null  $uniqueBy
     * @return bool
     */
    public function saveOrIgnore(array $options = [], array|string|null $uniqueBy = null)
    {
        if ($this->exists) {
            throw new LogicException('Cannot use saveOrIgnore on an existing model.');
        }

        $this->mergeAttributesFromCachedCasts();

        $query = $this->newModelQuery();

        if ($this->fireModelEvent('saving') === false) {
            return false;
        }

        $saved = $this->performInsertOrIgnore($query, $uniqueBy);

        if (! $this->getConnectionName() &&
            $connection = $query->getConnection()) {
            $this->setConnection($connection->getName());
        }

        if ($saved) {

View on GitHub (pinned to e0f6eb3518)