laravel/framework · error · InvalidArgumentException
Non-associative array passed to incrementEach method.
Error message
Non-associative array passed to incrementEach method.
What it means
Thrown by incrementEach when a key in the $columns array is not a string (i.e. the array is numerically/sequentially indexed rather than associative). incrementEach maps column-name => amount; a list like [5, 10] has no column names to target, so it is rejected. The is_numeric check runs first, so a numeric value list triggers the prior error.
Source
Thrown at src/Illuminate/Database/Query/Builder.php:4452
return $this->incrementEach([$column => $amount], $extra);
}
/**
* Increment the given column's values by the given amounts.
*
* @param array<string, float|int|numeric-string> $columns
* @param array<string, mixed> $extra
* @return int<0, max>
*
* @throws \InvalidArgumentException
*/
public function incrementEach(array $columns, array $extra = [])
{
foreach ($columns as $column => $amount) {
if (! is_numeric($amount)) {
throw new InvalidArgumentException("Non-numeric value passed as increment amount for column: '$column'.");
} elseif (! is_string($column)) {
throw new InvalidArgumentException('Non-associative array passed to incrementEach method.');
}
$columns[$column] = $this->raw("{$this->grammar->wrap($column)} + $amount");
}
return $this->update(array_merge($columns, $extra));
}
/**
* Decrement a column's value by a given amount.
*
* @param string $column
* @param float|int $amount
* @return int<0, max>
*
* @throws \InvalidArgumentException
*/
public function decrement($column, $amount = 1, array $extra = [])View on GitHub (pinned to bd6b5437e6)
Solutions
- Pass an associative array: `['views' => 1, 'score' => 5]`.
- Preserve keys during transforms: use `array_map` with keys via `array_combine(array_keys($a), array_map(..., $a))` or Laravel `collect(...)->mapWithKeys(...)`.
- Decode JSON as object when the source is a map: `json_decode($s, true)` only if the source is an object.
- Assert before calling: `if (array_keys($cols) === range(0, count($cols)-1)) throw ...`.
Example fix
// before
$amounts = array_map(fn ($v) => $v + 1, $request->all());
$model->incrementEach(array_values($amounts));
// => Non-associative array passed to incrementEach method.
// after
$pairs = ['views' => $request->integer('views', 0)];
$model->incrementEach($pairs); Defensive patterns
Strategy: type-guard
Validate before calling
if (array_keys($columns) === range(0, count($columns) - 1)) {
throw new \InvalidArgumentException('incrementEach expects an associative [column => amount] map.');
} Type guard
/** @param array<string, numeric> $a */
function isAssociativeMap(array $a): bool
{
return $a !== [] && array_keys($a) !== range(0, count($a) - 1);
} Try / catch
// This is a shape/type bug; validate the map before calling rather than catch.
Prevention
- Build amount maps with collect()->mapWithKeys() to preserve keys.
- Avoid array_values/array_map on the map before passing.
- Decode JSON maps as objects, not lists.
When it happens
Trigger: `incrementEach([5, 10])`. Passing `array_values($assoc)` which strips the keys. Building the map with `array_map` (which reindexes) instead of `array_mapWithKeys`/a comprehension.
Common situations: Transforming an associative map through a function that loses keys; merging maps where one side is a list; data from JSON that decoded as a list rather than an object.
Related errors
- Nested arrays may not be passed to whereIn method.
- Non-numeric value passed to increment method.
- Non-numeric value passed as increment amount for column: '$c
- Non-associative array passed to decrementEach method.
- A subquery must be a query builder instance, a Closure, or a
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/77d1f4a1d62c7e5f.json.
Report an issue: GitHub.