{"record":{"id":"8dc54a35e6cc07ac","repo":"laravel/framework","slug":"nested-arrays-may-not-be-passed-to-wherein-method","errorCode":null,"errorMessage":"Nested arrays may not be passed to whereIn method.","messagePattern":"Nested arrays may not be passed to whereIn method\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Query/Builder.php","lineNumber":1447,"sourceCode":"        if ($this->isQueryable($values)) {\n            [$query, $bindings] = $this->createSub($values);\n\n            $values = [new Expression($query)];\n\n            $this->addBinding($bindings, 'where');\n        }\n\n        // Next, if the value is Arrayable we need to cast it to its raw array form so we\n        // have the underlying array value instead of an Arrayable object which is not\n        // able to be added as a binding, etc. We will then add to the wheres array.\n        if ($values instanceof Arrayable) {\n            $values = $values->toArray();\n        }\n\n        $this->wheres[] = ['type' => $type, 'column' => $column, 'values' => $values, 'boolean' => $boolean];\n\n        if (count($values) !== count(Arr::flatten($values, 1))) {\n            throw new InvalidArgumentException('Nested arrays may not be passed to whereIn method.');\n        }\n\n        // Finally, we'll add a binding for each value unless that value is an expression\n        // in which case we will just skip over it since it will be the query as a raw\n        // string and not as a parameterized place-holder to be replaced by the PDO.\n        $this->addBinding($this->cleanBindings($values), 'where');\n\n        return $this;\n    }\n\n    /**\n     * Add an \"or where in\" clause to the query.\n     *\n     * @param  \\Illuminate\\Contracts\\Database\\Query\\Expression|string  $column\n     * @param  mixed  $values\n     * @return $this\n     */\n    public function orWhereIn($column, $values)","sourceCodeStart":1429,"sourceCodeEnd":1465,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Database/Query/Builder.php#L1429-L1465","documentation":"whereIn() stores its values array as bindings, and the grammar flattens exactly one level. After pushing the values into $this->wheres, the builder verifies count($values) === count(Arr::flatten($values, 1)); a mismatch means a nested array was passed, which would silently corrupt bindings or emit wrong SQL, so it throws InvalidArgumentException.","triggerScenarios":"->whereIn('id', [[1, 2], [3, 4]]), ->whereIn('role', $collectionOfArrays), or any case where an element of $values is itself an array (after Arrayable casting).","commonSituations":"Pluck()ing two columns and forgetting to extract one ('->pluck(['a','b'])'); groupBy + pluck returning nested structure; passing an Eloquent collection of models instead of an array of scalars; multi-column tuples mistakenly passed to whereIn.","solutions":["Flatten or map your input to a flat list of scalars before passing: ->whereIn('id', $rows->pluck('id')->all()).","For multi-column tuple matching use whereIn with an array of arrays via whereIn('col', $query) subquery form, or use whereRowValues per row.","Switch to whereJsonContains if you actually need array-membership semantics on a JSON column."],"exampleFix":"// before\n->whereIn('user_id', $orders->map(fn ($o) => $o->user_ids))  // user_ids is an array\n\n// after\n->whereIn('user_id', $orders->flatMap(fn ($o) => $o->user_ids))","handlingStrategy":"validation","validationCode":"if (Arr::isList($values) && count($values) === count(Arr::flatten($values, 1))) {\n    // safe: flat list of scalars\n}\n$values = array_values(Arr::flatten($values, 1)); // force-flatten to a scalar list\n$query->whereIn('id', $values);","typeGuard":"function isFlatScalarList(array $values): bool\n{\n    if (count($values) !== count(\\Illuminate\\Support\\Arr::flatten($values, 1))) {\n        return false;\n    }\n    foreach ($values as $v) {\n        if (is_array($v) || is_object($v) && ! ($v instanceof \\Illuminate\\Contracts\\Database\\Query\\Expression)) {\n            return false;\n        }\n    }\n    return true;\n}","tryCatchPattern":null,"preventionTips":["Map collections down to a single scalar column with ->pluck('col')->all() before whereIn().","Avoid multi-column tuples in whereIn; use whereRowValues or whereJsonContains instead.","Add a test that asserts whereIn input is flat when building queries dynamically."],"tags":["query-builder","where-in","database","types"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}