laravel/framework · error · InvalidArgumentException

Non-numeric value passed as increment amount for column: '$c

Error message

Non-numeric value passed as increment amount for column: '$column'.

What it means

Thrown by incrementEach when one of the per-column amounts fails is_numeric(). Unlike increment (single value), incrementEach takes an associative array of column => amount and validates each entry individually, naming the offending column in the message so you can locate the bad input.

Source

Thrown at src/Illuminate/Database/Query/Builder.php:4450

        }

        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

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Validate all amounts before the call: `$data = $request->validate(['*.amount' => 'numeric']);`.
  2. Cast each value: `array_map(fn($v) => is_numeric($v) ? $v + 0 : 0, $amounts)`.
  3. Inspect the named column in the error to locate the offending key in your input map.
  4. Decouple free-text fields from the increment map.

Example fix

// before
$model->incrementEach([
    'views' => $request->views,
    'score' => $request->score, // 'high'
]);
// => Non-numeric value passed as increment amount for column: 'score'.

// after
$amounts = collect(['views','score'])
    ->mapWithKeys(fn ($c) => [$c => (float) $request->input($c, 0)])
    ->toArray();
$model->incrementEach($amounts);
Defensive patterns

Strategy: validation

Validate before calling

foreach ($amounts as $col => $amt) {
    if (! is_numeric($amt)) {
        throw new \InvalidArgumentException("Amount for {$col} must be numeric.");
    }
}
$model->incrementEach($amounts);

Type guard

/** @param array<string, int|float|numeric-string> $a */
function allAmountsNumeric(array $a): bool
{
    return array_all($a, fn($v) => is_numeric($v));
}

Try / catch

// Validate the whole map before calling incrementEach; the error names the column to fix.

Prevention

When it happens

Trigger: `incrementEach(['views' => $req->views, 'score' => 'high'])` where 'high' is a non-numeric string. Building the amounts map from request input without numeric validation. Mixing a numeric column with a free-text field in one call.

Common situations: Batch counter APIs; admin tooling that increments several stats at once from a form; converting individual increment() calls into incrementEach() and inheriting unvalidated inputs.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/3baef3783287af5e.json. Report an issue: GitHub.