laravel/framework · error · InvalidArgumentException
The unique columns must not be empty.
Error message
The unique columns must not be empty.
What it means
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.
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.
Example fix
// before ->insertOrIgnoreReturning($rows, ['id'], $conflictCols) // $conflictCols = [] // after ->insertOrIgnoreReturning($rows, ['id'], ['id'])
Defensive patterns
Strategy: validation
Validate before calling
if ($uniqueBy === [] || $uniqueBy === '') {
throw new InvalidArgumentException('uniqueBy must reference the conflict column(s).');
}
$query->insertOrIgnoreReturning($rows, $returning, $uniqueBy); Prevention
- 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.
When it happens
Trigger: ->insertOrIgnoreReturning($rows, ['*'], []) or ->insertOrIgnoreReturning($rows, ['*'], ''), typically when $uniqueBy is computed and happens to be empty.
Common situations: Deriving $uniqueBy from a config that omitted the conflict column; passing [] by mistake; refactoring upsert calls and dropping the unique column argument.
Related errors
- The returning columns must not be empty.
- This database engine does not support inserting while…
- A subquery must be a query builder instance, a Closure, or…
- Cannot use saveOrIgnore on an existing model.
- $count records were found.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/113ebafef388e640.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Database/Query/Builder.php:4213
$this->cleanBindings(Arr::flatten($values, 1))
);
}
/**
* Insert new records into the database and returning specified columns with optional ignoring specific conflicts.
*
* @param non-empty-array<non-empty-string> $returning
* @param non-empty-string|non-empty-array<non-empty-string>|null $uniqueBy
* @return \Illuminate\Support\Collection
*/
public function insertOrIgnoreReturning(array $values, array $returning = ['*'], array|string|null $uniqueBy = null)
{
if (empty($values)) {
return new Collection;
}
if ($uniqueBy === [] || $uniqueBy === '') {
throw new InvalidArgumentException('The unique columns must not be empty.');
}
if ($returning === []) {
throw new InvalidArgumentException('The returning columns must not be empty.');
}
if (! is_array(array_first($values))) {
$values = [$values];
} else {
foreach ($values as $key => $value) {
ksort($value);
$values[$key] = $value;
}
}
$this->applyBeforeQueryCallbacks();
View on GitHub (pinned to e0f6eb3518)