laravel/framework · error · InvalidArgumentException
Nested arrays may not be passed to whereIn method.
Error message
Nested arrays may not be passed to whereIn method.
What it means
Thrown by whereIn after the values are stored: if count($values) !== count(Arr::flatten($values, 1)) the array contains nested arrays, which whereIn cannot represent as a flat IN-list. Laravel flattens one level for collections of Expression objects, but genuine multi-dimensional arrays (arrays of arrays of scalars) are rejected because they would produce malformed bindings or an unusable IN clause.
Source
Thrown at src/Illuminate/Database/Query/Builder.php:1447
if ($this->isQueryable($values)) {
[$query, $bindings] = $this->createSub($values);
$values = [new Expression($query)];
$this->addBinding($bindings, 'where');
}
// Next, if the value is Arrayable we need to cast it to its raw array form so we
// have the underlying array value instead of an Arrayable object which is not
// able to be added as a binding, etc. We will then add to the wheres array.
if ($values instanceof Arrayable) {
$values = $values->toArray();
}
$this->wheres[] = ['type' => $type, 'column' => $column, 'values' => $values, 'boolean' => $boolean];
if (count($values) !== count(Arr::flatten($values, 1))) {
throw new InvalidArgumentException('Nested arrays may not be passed to whereIn method.');
}
// Finally, we'll add a binding for each value unless that value is an expression
// in which case we will just skip over it since it will be the query as a raw
// string and not as a parameterized place-holder to be replaced by the PDO.
$this->addBinding($this->cleanBindings($values), 'where');
return $this;
}
/**
* Add an "or where in" clause to the query.
*
* @param \Illuminate\Contracts\Database\Query\Expression|string $column
* @param mixed $values
* @return $this
*/
public function orWhereIn($column, $values)View on GitHub (pinned to bd6b5437e6)
Solutions
- Flatten the array before passing: `whereIn('id', Arr::flatten($nested, 1))`.
- Use the inner collection directly: `whereIn('id', $group->pluck('id'))` instead of the outer structure.
- If you need OR-over-groups, build multiple orWhereIn clauses in a loop.
- Inspect with `dd(Arr::flatten($values))` to confirm the expected flat list.
Example fix
// before
$teams = User::all()->groupBy('team')->map->pluck('id')->toArray();
User::whereIn('id', $teams)->get();
// => Nested arrays may not be passed to whereIn method.
// after
$ids = \Illuminate\Support\Arr::flatten($teams, 1);
User::whereIn('id', $ids)->get(); Defensive patterns
Strategy: validation
Validate before calling
$flat = \Illuminate\Support\Arr::flatten($values, 1);
if (count($values) !== count($flat)) {
throw new InvalidArgumentException('whereIn values contain nested arrays; flattening required.');
}
$query->whereIn($col, $flat); Type guard
function isFlatArray(array $arr): bool
{
return count($arr) === count(\Illuminate\Support\Arr::flatten($arr, 1));
} Try / catch
// Validation is preferable. Catch only if the source shape is opaque:
try {
$q->whereIn('id', $ids);
} catch (\InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'Nested arrays')) {
$q->whereIn('id', \Illuminate\Support\Arr::flatten($ids, 1));
}
} Prevention
- Always pluck a single level: `->pluck('id')->all()` before whereIn.
- Run `Arr::flatten` on grouped/collection-derived inputs.
- Add a unit test asserting flat inputs to whereIn.
When it happens
Trigger: `whereIn('id', [[1,2],[3,4]])`. Passing a grouped result like `User::all()->groupBy('team')->map->pluck('id')->toArray()`. Accidentally wrapping a Collection in an array `[collect([1,2])]`. Passing the result of a `->toArray()` on a nested relationship payload.
Common situations: Pre-grouping IDs by category then feeding the grouped structure directly into whereIn; converting Eloquent collections of collections to arrays; off-by-one in a reduce/map that leaves an extra array layer.
Related errors
- Non-associative array passed to incrementEach method.
- Non-associative array passed to decrementEach method.
- A subquery must be a query builder instance, a Closure, or a
- The number of columns must match the number of values
- Order direction must be a SortDirection, "asc" or "desc".
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/8dc54a35e6cc07ac.json.
Report an issue: GitHub.