{"id":"1d03ca45add880c9","repo":"laravel/framework","slug":"s-records-were-found","errorCode":null,"errorMessage":"%s 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/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Database/Eloquent/Relations/Relation.php#L253-L289","documentation":"Relation::sole() (and Builder::sole()) fetch up to 2 rows and require exactly one. If more than one row matches, MultipleRecordsFoundException (RuntimeException) is thrown with the count, because 'sole' asserts the caller's expectation of uniqueness. It is distinct from ModelNotFoundException (zero rows).","triggerScenarios":"Calling ->sole() on a relation or query that matches 2+ rows, e.g. User::where('email', $e)->sole() when duplicates exist, or $user->latestPost()->sole() when there are multiple.","commonSituations":"Data with unintended duplicates (missing unique index); querying by a non-unique column; race conditions inserting duplicates before a unique constraint; using sole() where first() was intended.","solutions":["Use first() or firstOrFail() if more than one row may legitimately match.","Add a unique constraint/index at the DB level to enforce the uniqueness sole() assumes.","Tighten the where clause to guarantee a single row (e.g. add scope/order+limit 1 explicitly).","Catch MultipleRecordsFoundException to handle the ambiguity explicitly."],"exampleFix":"// before\n$post = User::where('slug', $slug)->sole(); // throws if duplicate slugs\n\n// after\n$post = User::where('slug', $slug)->firstOrFail();\n// or enforce uniqueness:\n// schema: $table->string('slug')->unique();","handlingStrategy":"try-catch","validationCode":"if ($query->count() > 1) {\n    throw new \\Illuminate\\Database\\MultipleRecordsFoundException($query->count());\n}\n$query->sole();","typeGuard":"function isUniqueMatch(\\Illuminate\\Database\\Eloquent\\Builder $query): bool {\n    return $query->clone()->limit(2)->count() === 1;\n}","tryCatchPattern":"try {\n    return $query->sole();\n} catch (\\Illuminate\\Database\\MultipleRecordsFoundException $e) {\n    // handle ambiguity: pick one, log, or fail\n    return $query->first();\n}","preventionTips":["Add unique indexes for columns queried with sole().","Use first()/firstOrFail() when duplicates may legitimately exist.","Tighten where clauses to guarantee a single row."],"tags":["eloquent","query-builder","sole","uniqueness","data-integrity"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}