laravel/framework · error · MultipleItemsFoundException
$count items were found.
Error message
$count items were found.
What it means
Thrown by Collection::sole() (via MultipleItemsFoundException) when more than one item matches the criteria. sole() asserts exactly one match and returns it, mirroring the database sole()/firstOrFail() pattern. The message includes the actual matched count so you can see how many duplicates exist. ItemNotFoundException is the counterpart for zero matches.
Source
Thrown at src/Illuminate/Collections/Collection.php:1460
* @throws \Illuminate\Support\ItemNotFoundException
* @throws \Illuminate\Support\MultipleItemsFoundException
*/
public function sole($key = null, $operator = null, $value = null)
{
$filter = func_num_args() > 1
? $this->operatorForWhere(...func_get_args())
: $key;
$items = $this->unless($filter == null)->filter($filter);
$count = $items->count();
if ($count === 0) {
throw new ItemNotFoundException;
}
if ($count > 1) {
throw new MultipleItemsFoundException($count);
}
return $items->first();
}
/**
* Determine if the collection contains a single item, optionally matching the given criteria.
*
* @param (callable(TValue, TKey): bool)|string|null $key
* @param mixed $operator
* @param mixed $value
* @return bool
*/
public function hasSole($key = null, $operator = null, $value = null): bool
{
$filter = func_num_args() > 1
? $this->operatorForWhere(...func_get_args())
: $key;View on GitHub (pinned to bd6b5437e6)
Solutions
- Ensure the matching criteria is actually unique; add a unique DB index/constraint on the field.
- Use first() instead of sole() if multiple matches are acceptable.
- Use sole() only after a unique-scoped query, or pre-filter to guarantee uniqueness.
Example fix
// before $user = User::all()->sole(fn ($u) => $u->email === $email); // after $user = User::whereEmail($email)->sole(); // DB-level unique, no dup risk
Defensive patterns
Strategy: try-catch
Validate before calling
$matches = $collection->filter($criteria); abort_if($matches->count() > 1, 409, 'Duplicate record'); $item = $matches->first();
Try / catch
try {
$item = $collection->sole('email', $email);
} catch (\Illuminate\Support\MultipleItemsFoundException $e) {
// log and pick deterministic first, or surface conflict
$item = $collection->where('email', $email)->first();
} catch (\Illuminate\Support\ItemNotFoundException $e) {
$item = null;
} Prevention
- Enforce uniqueness at the database layer (unique index) for any field used with sole().
- Prefer Eloquent/QueryBuilder sole() over Collection sole() so uniqueness is enforced server-side.
- In tests, assert exactly one matching row before assertions that rely on sole().
When it happens
Trigger: Calling $collection->sole() on a collection with 2+ items, or $collection->sole('status', 'active') when multiple items have status=active. Also sole(fn($u) => $u->role === 'admin') with several admins.
Common situations: Querying for a unique record (by email, token, slug) but the data has duplicates due to a missing unique constraint. Test fixtures seeding multiple matching rows. Lookup-by-unique-field assumptions that break when data integrity slips.
Related errors
- Array value for key [%s] must be an array, %s found.
- Array value for key [%s] must be a boolean, %s found.
- Array value for key [%s] must be a float, %s found.
- Items cannot be represented by a scalar value.
- Array value for key [%s] must be an integer, %s found.
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/8e60bba5192f5419.json.
Report an issue: GitHub.