laravel/framework · error · MultipleRecordsFoundException
$count records were found.
Error message
$count records were found.
What it means
Thrown by Builder::sole() when the query returns more than one row. sole() asserts the result set is exactly one record and raises MultipleRecordsFoundException (carrying the $count) when the count exceeds 1, so callers can detect uniqueness violations instead of silently picking the first.
Source
Thrown at src/Illuminate/Database/Concerns/BuildsQueries.php:407
*
* @param array|string $columns
* @return TValue
*
* @throws \Illuminate\Database\RecordsNotFoundException
* @throws \Illuminate\Database\MultipleRecordsFoundException
*/
public function sole($columns = ['*'])
{
$result = $this->limit(2)->get($columns);
$count = $result->count();
if ($count === 0) {
throw new RecordsNotFoundException;
}
if ($count > 1) {
throw new MultipleRecordsFoundException($count);
}
return $result->first();
}
/**
* Paginate the given query using a cursor paginator.
*
* @param int $perPage
* @param array|string $columns
* @param string $cursorName
* @param \Illuminate\Pagination\Cursor|string|null $cursor
* @return \Illuminate\Contracts\Pagination\CursorPaginator
*/
protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
{
if (! $cursor instanceof Cursor) {
$cursor = is_string($cursor)View on GitHub (pinned to bd6b5437e6)
Solutions
- Add a unique database index/constraint on the column you query via sole().
- Use firstOrFail() if you only need one row and duplicates are tolerable.
- Catch Illuminate\Database\MultipleRecordsFoundException to handle the violation explicitly.
- Narrow the query (->latest()->sole() etc.) or deduplicate the data first.
Example fix
// before
$license = License::where('key', $key)->sole();
// throws when two rows share the key
// after
// 1. add unique index: $table->string('key')->unique();
// 2. handle gracefully:
use Illuminate\Database\MultipleRecordsFoundException;
try {
$license = License::where('key', $key)->sole();
} catch (MultipleRecordsFoundException $e) {
abort(409, 'Duplicate license key: '.$e->count.' found.');
} Defensive patterns
Strategy: try-catch
Validate before calling
$count = Model::where('key', $key)->count();
if ($count > 1) {
throw new \RuntimeException("{$count} duplicates found");
} Type guard
function isUnique(\Illuminate\Database\Eloquent\Builder $q): bool { return $q->count() <= 1; } Try / catch
use Illuminate\Database\MultipleRecordsFoundException;
try {
$rec = Model::where('key', $key)->sole();
} catch (MultipleRecordsFoundException $e) {
abort(409, "{$e->count} records found");
} Prevention
- Add unique indexes on columns queried via sole().
- Use firstOrFail when duplicates are tolerable.
- Catch MultipleRecordsFoundException for explicit handling.
When it happens
Trigger: User::where('email', $email)->sole() where the email column is not unique and two rows match; looking up by a field you believed unique; race condition inserting a duplicate between check and use.
Common situations: Missing unique index on a column queried via sole(); data migration that created duplicates; querying by a non-unique attribute (name, status) where multiple rows legitimately match; soft-deleted duplicates.
Related errors
- The chunkById operation was aborted because the [{$alias}] c
- No record found for the given query.
- %s records were found.
- The lazyById operation was aborted because the [{$alias}] co
- Property [{$key}] does not exist on the Eloquent builder ins
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/b01aa82089049e03.json.
Report an issue: GitHub.