briannesbitt/Carbon · error · UnitException
Unable to add unit '.var_export($originalArgs, true)
Error message
Unable to add unit '.var_export($originalArgs, true)
What it means
addUnit() (also reachable via add()/subUnit()/subtract()) converts the unit and value to a CarbonInterval or falls back to DateTime::modify inside rawAddUnit(); if that pipeline throws UnsupportedUnitException, DateMalformedStringException or InvalidFormatException, the date result is null and Carbon rethrows UnitException with var_export() of the original arguments and the root cause chained as previous. It is the catch-all 'the unit/value pair could not be applied' error, so the real reason is in getPrevious().
Source
Thrown at src/Carbon/Traits/Units.php:394
$date = self::rawAddUnit($date, $unit, $value);
if ($date !== null) {
if (isset($timeString)) {
$date = $date->setTimeFromTimeString($timeString);
} elseif (isset($canOverflow, $day) && $canOverflow && $day !== $date->day) {
$date = $date->modify('last day of previous month');
}
if ($anchorDay !== null) {
$date = $date->setAnchorDay($anchorDay);
}
}
} catch (DateMalformedStringException|InvalidFormatException|UnsupportedUnitException $exception) {
$date = null;
$previousException = $exception;
}
return $date ?? throw new UnitException(
'Unable to add unit '.var_export($originalArgs, true),
previous: $previousException,
);
}
/**
* Subtract given units to the current instance.
*/
public function subUnit(
Unit|string $unit,
$value = 1,
OverflowMode|bool|null $overflow = null,
?int $anchorDay = null,
): static {
return $this->addUnit($unit, -$value, $overflow, $anchorDay);
}
/**View on GitHub (pinned to b13f05955d)
Solutions
- Inspect getPrevious() on the caught UnitException: UnsupportedUnitException means the unit is unrecognized, DateMalformedStringException/InvalidFormatException points at the value/string
- Fix or whitelist the unit against the Unit enum / supported list before calling addUnit
- Clamp or bound computed values (reject |value| beyond a sane range) before passing them in
- Catch UnitException at the boundary and map it to a 422/validation error instead of a 500
Example fix
// before
$date->addUnit($unitFromRequest, $amount);
// after
try {
$date->addUnit($unitFromRequest, $amount);
} catch (UnitException $e) {
$reason = $e->getPrevious() ? get_class($e->getPrevious()) : 'unknown';
throw new InvalidArgumentException("Cannot apply $amount $unitFromRequest ($reason)", 0, $e);
} Defensive patterns
Strategy: try-catch
Validate before calling
$value = (float) $amount;
if (!is_finite($value) || abs($value) > 1e9) {
throw new InvalidArgumentException("Refusing to add unrealistic amount: $amount");
}
if (!$unit instanceof Unit && !in_array((string) $unit, array_map(fn (Unit $u) => $u->value, Unit::cases()), true)) {
throw new InvalidArgumentException("Unknown unit: $unit");
} Type guard
function isKnownUnit(mixed $unit): bool
{
if ($unit instanceof Unit) {
return true;
}
static $names;
$names ??= array_map(fn (Unit $u) => $u->value, Unit::cases());
return in_array(Carbon::singularUnit(strtolower((string) $unit)), $names, true);
} Try / catch
use Carbon\Exceptions\UnitException;
try {
$result = $date->addUnit($unit, $value);
} catch (UnitException $e) {
$root = $e->getPrevious(); // UnsupportedUnitException | InvalidFormatException | DateMalformedStringException
logger()->warning('addUnit failed', ['unit' => $unit, 'value' => $value, 'root' => $root]);
throw new ValidationException('Unsupported date arithmetic');
} Prevention
- Always inspect getPrevious() - the outer UnitException hides the real cause
- Bound user-supplied magnitudes before date arithmetic; PHP date range is year 1-9999
- Centralize unit validation with the Unit enum at your input layer
When it happens
Trigger: $date->addUnit('fortnight', 3) where neither CarbonInterval::fromString('3 fortnight') nor modify('3 fortnight') parses; $date->add(5, 'dayz') typo; a string value like 'NaN' or INF surviving is_numeric guards in float form and producing a malformed modify string; huge computed values (e.g. 1e17 years) that overflow PHP's date range during the fallback modify.
Common situations: Unit typos in migrated code; unit enums/strings from external input passed unvalidated; arithmetic on user-supplied quantities producing astronomically large values; Carbon major upgrades where a previously tolerated unit string is no longer parsed by the interval parser.
Related errors
- Unsupported unit '$unit'
- Unknown unit '$unit'.
- Invalid unit for real timestamp add/sub: '$unit'
- Invalid serialized value: $value
- $anchorDay must be greater than 0
AI-assisted analysis of briannesbitt/Carbon@b13f05955d (2026-08-17).
Data as JSON: /api/errors/c5779c5aed670403.
Report an issue: GitHub.