{"record":{"id":"113ebafef388e640","repo":"laravel/framework","slug":"the-unique-columns-must-not-be-empty","errorCode":null,"errorMessage":"The unique columns must not be empty.","messagePattern":"The unique columns must not be empty\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Query/Builder.php","lineNumber":4213,"sourceCode":"            $this->cleanBindings(Arr::flatten($values, 1))\n        );\n    }\n\n    /**\n     * Insert new records into the database and returning specified columns with optional ignoring specific conflicts.\n     *\n     * @param  non-empty-array<non-empty-string>  $returning\n     * @param  non-empty-string|non-empty-array<non-empty-string>|null  $uniqueBy\n     * @return \\Illuminate\\Support\\Collection\n     */\n    public function insertOrIgnoreReturning(array $values, array $returning = ['*'], array|string|null $uniqueBy = null)\n    {\n        if (empty($values)) {\n            return new Collection;\n        }\n\n        if ($uniqueBy === [] || $uniqueBy === '') {\n            throw new InvalidArgumentException('The unique columns must not be empty.');\n        }\n\n        if ($returning === []) {\n            throw new InvalidArgumentException('The returning columns must not be empty.');\n        }\n\n        if (! is_array(array_first($values))) {\n            $values = [$values];\n        } else {\n            foreach ($values as $key => $value) {\n                ksort($value);\n\n                $values[$key] = $value;\n            }\n        }\n\n        $this->applyBeforeQueryCallbacks();\n","sourceCodeStart":4195,"sourceCodeEnd":4231,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Database/Query/Builder.php#L4195-L4231","documentation":"insertOrIgnoreReturning() requires a non-empty $uniqueBy argument because the returning/upsert semantics only make sense keyed on conflict columns. An empty array or empty string is rejected before SQL is built, since 'INSERT ... ON CONFLICT ()' would be invalid.","triggerScenarios":"->insertOrIgnoreReturning($rows, ['*'], []) or ->insertOrIgnoreReturning($rows, ['*'], ''), typically when $uniqueBy is computed and happens to be empty.","commonSituations":"Deriving $uniqueBy from a config that omitted the conflict column; passing [] by mistake; refactoring upsert calls and dropping the unique column argument.","solutions":["Supply the conflict column(s): ->insertOrIgnoreReturning($rows, ['id'], 'id').","Validate the computed $uniqueBy is non-empty before calling, with a clear domain error.","If you do not need ON CONFLICT semantics, use plain insertOrIgnore() instead."],"exampleFix":"// before\n->insertOrIgnoreReturning($rows, ['id'], $conflictCols)  // $conflictCols = []\n\n// after\n->insertOrIgnoreReturning($rows, ['id'], ['id'])","handlingStrategy":"validation","validationCode":"if ($uniqueBy === [] || $uniqueBy === '') {\n    throw new InvalidArgumentException('uniqueBy must reference the conflict column(s).');\n}\n$query->insertOrIgnoreReturning($rows, $returning, $uniqueBy);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat $uniqueBy as required domain data, not optional config.","Validate the conflict column list at the boundary (controller/job) before it reaches the builder.","Fall back to insertOrIgnore() when no conflict target is needed."],"tags":["query-builder","insert","upsert","database","postgresql"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}