{"id":"8e60bba5192f5419","repo":"laravel/framework","slug":"count-items-were-found-8e60bb","errorCode":null,"errorMessage":"$count items were found.","messagePattern":"\\$count items were found\\.","errorType":"exception","errorClass":"MultipleItemsFoundException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Collections/Collection.php","lineNumber":1460,"sourceCode":"     * @throws \\Illuminate\\Support\\ItemNotFoundException\n     * @throws \\Illuminate\\Support\\MultipleItemsFoundException\n     */\n    public function sole($key = null, $operator = null, $value = null)\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;\n\n        $items = $this->unless($filter == null)->filter($filter);\n\n        $count = $items->count();\n\n        if ($count === 0) {\n            throw new ItemNotFoundException;\n        }\n\n        if ($count > 1) {\n            throw new MultipleItemsFoundException($count);\n        }\n\n        return $items->first();\n    }\n\n    /**\n     * Determine if the collection contains a single item, optionally matching the given criteria.\n     *\n     * @param  (callable(TValue, TKey): bool)|string|null  $key\n     * @param  mixed  $operator\n     * @param  mixed  $value\n     * @return bool\n     */\n    public function hasSole($key = null, $operator = null, $value = null): bool\n    {\n        $filter = func_num_args() > 1\n            ? $this->operatorForWhere(...func_get_args())\n            : $key;","sourceCodeStart":1442,"sourceCodeEnd":1478,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Collections/Collection.php#L1442-L1478","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n$user = User::all()->sole(fn ($u) => $u->email === $email);\n\n// after\n$user = User::whereEmail($email)->sole(); // DB-level unique, no dup risk","handlingStrategy":"try-catch","validationCode":"$matches = $collection->filter($criteria);\nabort_if($matches->count() > 1, 409, 'Duplicate record');\n$item = $matches->first();","typeGuard":null,"tryCatchPattern":"try {\n    $item = $collection->sole('email', $email);\n} catch (\\Illuminate\\Support\\MultipleItemsFoundException $e) {\n    // log and pick deterministic first, or surface conflict\n    $item = $collection->where('email', $email)->first();\n} catch (\\Illuminate\\Support\\ItemNotFoundException $e) {\n    $item = null;\n}","preventionTips":["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()."],"tags":["laravel","collections","data-integrity","uniqueness"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}