laravel/framework · error · MultipleRecordsFoundException
{$count} records were found.
Error message
{$count} records were found. What it means
Relation::sole() executes the relationship query expecting exactly one matching row. It runs with limit(2); if more than one row is returned it throws MultipleRecordsFoundException carrying the count. sole() is the strict counterpart to first() and is used when the developer asserts the relation matches a single record.
Source
Thrown at src/Illuminate/Database/Eloquent/Relations/Relation.php:271
*
* @param array|string $columns
* @return TRelatedModel
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException<TRelatedModel>
* @throws \Illuminate\Database\MultipleRecordsFoundException
*/
public function sole($columns = ['*'])
{
$result = $this->limit(2)->get($columns);
$count = $result->count();
if ($count === 0) {
throw (new ModelNotFoundException)->setModel(get_class($this->related));
}
if ($count > 1) {
throw new MultipleRecordsFoundException($count);
}
return $result->first();
}
/**
* Execute the query as a "select" statement.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Collection<int, TRelatedModel>
*/
public function get($columns = ['*'])
{
return $this->query->get($columns);
}
/**
* Touch all of the related models for the relationship.View on GitHub (pinned to e0f6eb3518)
Solutions
- Tighten the query with where() so only one row can match before calling sole().
- Use first() or firstOrFail() if more than one row is acceptable.
- Catch \Illuminate\Database\MultipleRecordsFoundException and decide recovery (pick latest, error out, etc.).
- Fix the underlying data - deduplicate the rows that caused the ambiguity.
Example fix
// before $latest = $user->orders()->sole(); // throws if user has >1 order // after - constrain to exactly one $latest = $user->orders()->latest()->sole(); // or accept the first $any = $user->orders()->first();
Defensive patterns
Strategy: try-catch
Validate before calling
// If more than one row may match, do not use sole(). Constrain first.
// Optional pre-count guard:
$count = $model->relation()->count();
if ($count > 1) {
throw new \RuntimeException('Relation matches multiple rows; tighten the query before sole().');
}
$model->relation()->sole(); Try / catch
try {
$item = $user->orders()->sole();
} catch (\Illuminate\Database\MultipleRecordsFoundException $e) {
// multiple matched - recover by picking latest, or surface error
$item = $user->orders()->latest()->first();
} Prevention
- Use sole() only when the schema/data guarantees at most one match (unique constraints, scoped queries).
- Add where()/orderBy()->limit(1) before sole() when the relation can legitimately have several rows.
- Prefer first()/firstOrFail() when more than one match is acceptable.
- Catch MultipleRecordsFoundException at the boundary and choose recovery explicitly.
When it happens
Trigger: Calling $model->relation()->sole() or any query scope ending in sole() on a relation that matches 2+ rows. The message '{$count} records were found.' comes from MultipleRecordsFoundException.
Common situations: Assuming a hasMany/belongsToMany matches exactly one when the data has duplicates; using sole() in seeders/tests where duplicate fixtures exist; race conditions inserting a second row before sole() runs.
Related errors
- Global scope must be an instance of Closure or Scope or be a
- Resource collection guesser expects the collection to contai
- Expected class %s to implement guessResourceName method. Mak
- Failed to find resource class for model [%s].
- No record found for the given query.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/d27dfc8dac1fb64a.
Report an issue: GitHub.