{"record":{"id":"d27dfc8dac1fb64a","repo":"laravel/framework","slug":"count-records-were-found-d27dfc","errorCode":null,"errorMessage":"{$count} records were found.","messagePattern":"(.+?) records were found\\.","errorType":"exception","errorClass":"MultipleRecordsFoundException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Eloquent/Relations/Relation.php","lineNumber":271,"sourceCode":"     *\n     * @param  array|string  $columns\n     * @return TRelatedModel\n     *\n     * @throws \\Illuminate\\Database\\Eloquent\\ModelNotFoundException<TRelatedModel>\n     * @throws \\Illuminate\\Database\\MultipleRecordsFoundException\n     */\n    public function sole($columns = ['*'])\n    {\n        $result = $this->limit(2)->get($columns);\n\n        $count = $result->count();\n\n        if ($count === 0) {\n            throw (new ModelNotFoundException)->setModel(get_class($this->related));\n        }\n\n        if ($count > 1) {\n            throw new MultipleRecordsFoundException($count);\n        }\n\n        return $result->first();\n    }\n\n    /**\n     * Execute the query as a \"select\" statement.\n     *\n     * @param  array  $columns\n     * @return \\Illuminate\\Database\\Eloquent\\Collection<int, TRelatedModel>\n     */\n    public function get($columns = ['*'])\n    {\n        return $this->query->get($columns);\n    }\n\n    /**\n     * Touch all of the related models for the relationship.","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Database/Eloquent/Relations/Relation.php#L253-L289","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n$latest = $user->orders()->sole(); // throws if user has >1 order\n\n// after - constrain to exactly one\n$latest = $user->orders()->latest()->sole();\n// or accept the first\n$any = $user->orders()->first();","handlingStrategy":"try-catch","validationCode":"// If more than one row may match, do not use sole(). Constrain first.\n// Optional pre-count guard:\n$count = $model->relation()->count();\nif ($count > 1) {\n    throw new \\RuntimeException('Relation matches multiple rows; tighten the query before sole().');\n}\n$model->relation()->sole();","typeGuard":null,"tryCatchPattern":"try {\n    $item = $user->orders()->sole();\n} catch (\\Illuminate\\Database\\MultipleRecordsFoundException $e) {\n    // multiple matched - recover by picking latest, or surface error\n    $item = $user->orders()->latest()->first();\n}","preventionTips":["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."],"tags":["eloquent","query","sole","multiple-records","assertion"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}