laravel/framework · error · LogicException
Cannot use saveOrIgnore on an existing model.
Error message
Cannot use saveOrIgnore on an existing model.
What it means
saveOrIgnore() inserts a new row ignoring unique-constraint conflicts (INSERT IGNORE semantics) and is only valid for models not yet persisted. The guard at the top rejects calls when $this->exists is true, because an existing model would need an UPDATE path, not an INSERT-OR-IGNORE.
Source
Thrown at src/Illuminate/Database/Eloquent/Model.php:1433
// 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 bd6b5437e6)
Solutions
- Use save() or update() for existing models instead of saveOrIgnore().
- Instantiate a new model (new Model([...])) before calling saveOrIgnore() so $exists is false.
- For upsert behavior on existing rows, use upsert() or firstOrCreate()/updateOrCreate() depending on intent.
Example fix
// before $user = User::find($id); $user->saveOrIgnore(); // throws // after $user->save(); // or for insert-or-ignore on a new row: User::createOrFirst(['email' => $email], [...]);
Defensive patterns
Strategy: type-guard
Validate before calling
if ($model->exists) {
throw new \LogicException('Cannot saveOrIgnore on existing '.get_class($model).'; use save().');
}
$model->saveOrIgnore(); Type guard
function isInsertable(\Illuminate\Database\Eloquent\Model $model): bool {
return ! $model->exists;
} Prevention
- Check $model->exists before saveOrIgnore; use save()/update() for existing rows.
- Reserve saveOrIgnore for freshly instantiated models.
- Prefer createOrFirst()/upsert() for insert-or-match semantics.
When it happens
Trigger: Calling $existingModel->saveOrIgnore() on a model loaded from the database ($exists === true), e.g. reusing a fetched instance and attempting to insert-or-ignore it again.
Common situations: Treating saveOrIgnore as a generic upsert; passing a model retrieved via find()/first()/firstOrCreate() to saveOrIgnore instead of a freshly instantiated one; copy-paste from a create flow to an update flow.
Related errors
- The chunkById operation was aborted because the [{$alias}] c
- The lazyById operation was aborted because the [{$alias}] co
- No record found for the given query.
- $count records were found.
- The --model and --except options cannot be combined.
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/653682c12c7d3c5b.json.
Report an issue: GitHub.