laravel/framework · error · UnexpectedValueException
Collection should only include
Error message
Collection should only include [%s] items, but '%s' found at position %d.
What it means
Thrown by Collection::ensure($type) when an item in the collection does not match any of the allowed types. The method iterates every item, compares get_debug_type($item) against the allowed list (and an instanceof check), and throws UnexpectedValueException at the first mismatch with the position and actual type. It is the runtime type-enforcement analogue of PHPDoc generics.
Solutions
- Filter/map the collection to the expected type before calling ensure.
- Pass an array of allowed types to accept a union: ->ensure(['int','string']).
- Fix the upstream producer so only valid items enter the collection.
Example fix
// before $collection->ensure(User::class); // after $users = $collection->filter(fn ($i) => $i instanceof User); $users->ensure(User::class);
Defensive patterns
Strategy: type-guard
Validate before calling
$allowed = [\App\Models\User::class];
$bad = $collection->first(fn ($i) => ! (is_object($i) && ($i instanceof \App\Models\User)));
if ($bad !== null) {
throw new \UnexpectedValueException('Collection contains non-User item.');
}
$collection->ensure(\App\Models\User::class); Type guard
function isUserCollection(\Illuminate\Support\Collection $c): bool {
return $c->every(fn ($i) => $i instanceof \App\Models\User);
} Try / catch
try {
$collection->ensure(\App\Models\User::class);
} catch (\UnexpectedValueException $e) {
// log and filter out offending items
$collection = $collection->filter(fn ($i) => $i instanceof \App\Models\User);
} Prevention
- Type-check items at the producer boundary (DB, API, CSV import).
- Use every() to validate before ensure() in defensive code paths.
- Prefer Eloquent collections which are already typed over generic ones.
When it happens
Trigger: ->ensure(User::class) when the collection contains a non-User object or a scalar; ->ensure(['int','string']) when a null/float is present; mixing data from a query that returned unexpected rows.
Common situations: Collection built from an external/unguarded source (CSV, API payload, DB raw query) that includes nulls or unexpected types; refactoring a heterogeneous collection to typed after the fact.
Related errors
- Number of groups must be at least 1.
- Number of shifted items may not be less than zero.
- Size value must be at least 1.
- Step value must be at least 1.
- You requested items, but there are only items available.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/fe3d63f527963038.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Collections/Traits/EnumeratesValues.php:398
* @param class-string<TEnsureOfType>|array<array-key, class-string<TEnsureOfType>>|'string'|'int'|'float'|'bool'|'array'|'null' $type
* @return static<TKey, TEnsureOfType>
*
* @throws \UnexpectedValueException
*/
public function ensure($type)
{
$allowedTypes = is_array($type) ? $type : [$type];
return $this->each(function ($item, $index) use ($allowedTypes) {
$itemType = get_debug_type($item);
foreach ($allowedTypes as $allowedType) {
if ($itemType === $allowedType || $item instanceof $allowedType) {
return true;
}
}
throw new UnexpectedValueException(
sprintf("Collection should only include [%s] items, but '%s' found at position %d.", implode(', ', $allowedTypes), $itemType, $index)
);
});
}
/**
* Determine if the collection is not empty.
*
* @phpstan-assert-if-true TValue $this->first()
* @phpstan-assert-if-true TValue $this->last()
*
* @phpstan-assert-if-false null $this->first()
* @phpstan-assert-if-false null $this->last()
*
* @return bool
*/
public function isNotEmpty()
{View on GitHub (pinned to e0f6eb3518)