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
- For inserts of new records, use a fresh model: $m = new Model; $m->fill(...); $m->saveOrIgnore();.
- For existing records, call save() or update() instead of saveOrIgnore().
- If you replicated a model, the copy already has exists=false; otherwise unset it, but prefer new instances.
- 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
- Treat saveOrIgnore as insert-only - never call it on a model loaded from the DB.
- Use new Model([...]) (or Model::make([...])) for idempotent inserts.
- For upsert semantics on possibly-existing rows, use upsert() or insertOrIgnore() at the query level.
- After replicate(), the copy is already new - safe to saveOrIgnore.
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
- The unique columns must not be empty.
- This database engine does not support inserting while…
- Add fillable property
- Add [ ] to fillable property to allow mass assignment on […
- Call to undefined cast
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)