{"record":{"id":"3a90ee9c263720ca","repo":"laravel/framework","slug":"the-number-of-columns-must-match-the-number-of-val","errorCode":null,"errorMessage":"The number of columns must match the number of values","messagePattern":"The number of columns must match the number of values","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Query/Builder.php","lineNumber":2226,"sourceCode":"\n        return $this;\n    }\n\n    /**\n     * Adds a where condition using row values.\n     *\n     * @param  array  $columns\n     * @param  string  $operator\n     * @param  array  $values\n     * @param  string  $boolean\n     * @return $this\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function whereRowValues($columns, $operator, $values, $boolean = 'and')\n    {\n        if (count($columns) !== count($values)) {\n            throw new InvalidArgumentException('The number of columns must match the number of values');\n        }\n\n        $type = 'RowValues';\n\n        $this->wheres[] = ['type' => $type, 'columns' => $columns, 'operator' => $operator, 'values' => $values, 'boolean' => $boolean];\n\n        $this->addBinding($this->cleanBindings($values));\n\n        return $this;\n    }\n\n    /**\n     * Adds an or where condition using row values.\n     *\n     * @param  array  $columns\n     * @param  string  $operator\n     * @param  array  $values\n     * @return $this","sourceCodeStart":2208,"sourceCodeEnd":2244,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Database/Query/Builder.php#L2208-L2244","documentation":"whereRowValues() builds a row-value comparison such as (a, b) = (1, 2). The SQL is only well-formed when the column tuple and value tuple have the same arity, so the method hard-asserts count($columns) === count($values) and throws InvalidArgumentException otherwise.","triggerScenarios":"->whereRowValues(['col_a', 'col_b'], '=', [1]), or any call where the columns array and values array have different lengths.","commonSituations":"Building row-value filters from form input where one side was omitted; refactoring a query and forgetting to keep both arrays in sync; passing a single-element values array for a multi-column key.","solutions":["Make the columns and values arrays come from a single source of truth so their lengths cannot diverge.","Add an explicit count() assertion in your calling code with a clearer message before reaching the builder.","Fall back to a chain of plain where() calls if the row-value form is not required."],"exampleFix":"// before\n->whereRowValues(['tenant_id', 'user_id'], '=', [$tenant])\n\n// after\n->whereRowValues(['tenant_id', 'user_id'], '=', [$tenant, $user])","handlingStrategy":"validation","validationCode":"if (count($columns) !== count($values)) {\n    throw new InvalidArgumentException('columns/values length mismatch');\n}\n$query->whereRowValues($columns, $operator, $values);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Drive columns and values from the same source so lengths stay in sync.","Add a count() assertion in calling code with a domain-specific message.","Favor plain where() chains unless you specifically need row-value tuple SQL."],"tags":["query-builder","row-values","database","validation"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}