briannesbitt/Carbon · error · InvalidArgumentException
Interval objects cannot be multiplied by a non-integer value
Error message
Interval objects cannot be multiplied by a non-integer value.
What it means
When the first argument of add()/sub() is an interval-like value (CarbonInterval, DateInterval converted to closure, CarbonConverterInterface or a Closure), Carbon applies it N times in a loop where the count must be a whole number. disallowDecimalPart() compares the float value against its int cast and throws InvalidArgumentException for any fractional multiplier such as 1.5 or 0.5 - you cannot apply an interval one and a half times.
Source
Thrown at src/Carbon/Traits/Units.php:609
}
/**
* Set current day of the instance to the passed value if it exits in the
* current month, else set current day to the last day of the month.
*/
public function setAnchorDay(int $anchorDay): static
{
if ($anchorDay < 1) {
throw new InvalidArgumentException('$anchorDay must be greater than 0');
}
return $this->day(min($anchorDay, $this->daysInMonth));
}
private static function disallowDecimalPart(mixed $value): void
{
if (((float) $value) !== ((float) (int) $value)) {
throw new InvalidArgumentException(
'Interval objects cannot be multiplied by a non-integer value.',
);
}
}
private function getOverflowMode(
OverflowMode|bool|null $overflow = null,
?int $anchorDay = null,
): ?OverflowMode {
if ($anchorDay !== null) {
$overflow ??= OverflowMode::AnchorDay;
if ($overflow !== OverflowMode::AnchorDay) {
throw new InvalidArgumentException(
'$anchorDay can be set only $overflow = OverflowMode::AnchorDay',
);
}
}View on GitHub (pinned to b13f05955d)
Solutions
- Convert the fraction into smaller units before adding: instead of add(CarbonInterval::days(2), 1.5) use ->addUnit('hour', 72) or CarbonInterval::hours(72)
- Round/cast the multiplier deliberately: (int) floor($times) or ceil() per business rule, and handle the remainder explicitly
- If you need fractional interval scaling, use CarbonInterval's own float-capable multiplication (e.g. CarbonInterval::fromString('2 days')->times(1.5)) and add the resulting interval once
- Validate fmod($times, 1) === 0.0 at the boundary when the count comes from division
Example fix
// before $date->add(CarbonInterval::days(2), 1.5); // throws // after $date->add(CarbonInterval::hours(72)); // 1.5 x 2 days expressed exactly
Defensive patterns
Strategy: validation
Validate before calling
$times = (float) $count;
if (fmod($times, 1.0) !== 0.0) {
throw new InvalidArgumentException("Interval repeat count must be an integer, got $count");
}
$date->add($interval, (int) $times); Type guard
function isIntegerMultiplier(int|float|string $value): bool
{
return is_int($value) || (is_float($value) && fmod($value, 1.0) === 0.0)
|| (is_string($value) && preg_match('/^-?\d+$/', $value) === 1);
} Try / catch
try {
$date->add($interval, $times);
} catch (\InvalidArgumentException $e) {
// fractional count: split into whole repeats + remainder in smaller units
$date->add($interval, (int) floor($times));
$date->addUnit('hour', $interval->totalHours * fmod($times, 1.0));
} Prevention
- Express fractional durations in smaller units (hours/minutes) instead of fractional multipliers
- When the count comes from division, decide floor vs ceil explicitly and handle the remainder
- For true float scaling, use CarbonInterval's float-capable times() and add the result once
When it happens
Trigger: $date->add(CarbonInterval::days(2), 1.5); $date->add($someIntervalConverter, 0.5); a computed multiplier like $total / $chunkSize that lands on 2.25; passing '1.5' as a numeric string multiplier; passing -1.5 to invert and scale an interval in sub().
Common situations: Generic 'repeat interval X times' helpers receiving user quotas that are not multiples of the chunk; batch/split logic computing counts by division; migrating code that multiplied CarbonInterval::times(...) (which supports floats on some units) into the add(..., $times) signature which does not.
Related errors
- Unknown unit '$unit'.
- Invalid serialized value: $value
- Invalid unit for real timestamp add/sub: '$unit'
- Unable to add unit '.var_export($originalArgs, true)
- Unsupported unit '$unit'
AI-assisted analysis of briannesbitt/Carbon@b13f05955d (2026-08-17).
Data as JSON: /api/errors/ffcbab1d8c2a7b4e.
Report an issue: GitHub.