briannesbitt/Carbon · error · InvalidPeriodParameterException
Invalid constructor parameters.
Error message
Invalid constructor parameters.
What it means
The CarbonPeriod constructor (and create()) sorts its variadic arguments by type: DateInterval/CarbonInterval become the interval, DateTimeInterface objects become start then end, non-negative int/float become recurrences, int/null become the options bitmask, DateTimeZone or a timezone-name string become the timezone, other strings are tried as ISO specs or dates. An argument matching none of these categories is unusable and throws InvalidPeriodParameterException (src/Carbon/CarbonPeriod.php:808).
Source
Thrown at src/Carbon/CarbonPeriod.php:808
} elseif (!isset($sortedArguments['start']) && $parsedDate = $this->makeDateTime($argument)) {
$sortedArguments['start'] = $parsedDate;
$originalArguments['start'] = $argument;
} elseif (!isset($sortedArguments['end']) && ($parsedDate = $parsedDate ?? $this->makeDateTime($argument))) {
$sortedArguments['end'] = $parsedDate;
$originalArguments['end'] = $argument;
} elseif (!isset($sortedArguments['recurrences']) &&
!isset($sortedArguments['end']) &&
(\is_int($argument) || \is_float($argument))
&& $argument >= 0
) {
$sortedArguments['recurrences'] = $argument;
} elseif (!$optionsSet && (\is_int($argument) || $argument === null)) {
$optionsSet = true;
$sortedArguments['options'] = (((int) $this->options) | ((int) $argument));
} elseif ($parsedTimezone = self::makeTimezone($argument)) {
$sortedArguments = $this->configureTimezone($parsedTimezone, $sortedArguments, $originalArguments);
} else {
throw new InvalidPeriodParameterException('Invalid constructor parameters.');
}
}
$this->setFromAssociativeArray($sortedArguments);
if ($this->startDate === null) {
$dateClass = $this->dateClass;
$this->setStartDate($dateClass::now());
}
if ($this->dateInterval === null) {
$this->setDateInterval(CarbonInterval::day());
$this->isDefaultInterval = true;
}
if ($this->options === null) {
$this->setOptions(0);View on GitHub (pinned to b13f05955d)
Solutions
- Pass recognized types only: parseable date strings, DateTimeInterface, DateInterval/CarbonInterval, non-negative numbers, DateTimeZone
- Spread parameter arrays: CarbonPeriod::create(...$args), not create($args)
- Sanitize at the boundary: convert input to Carbon::parse()/CarbonInterval::make() results before the constructor sees them
Example fix
// before $period = new CarbonPeriod($params); // $params is an array -> Invalid constructor parameters // after $period = CarbonPeriod::create(...$params); // before $period = CarbonPeriod::create($userInput); // 'garbage' // after $period = CarbonPeriod::create(Carbon::parse($userInput));
Defensive patterns
Strategy: validation
Validate before calling
foreach ($arguments as $argument) {
$ok = $argument instanceof DateTimeInterface
|| $argument instanceof DateInterval
|| $argument instanceof DateTimeZone
|| \is_string($argument)
|| (\is_int($argument) || \is_float($argument)) && $argument >= 0
|| $argument === null;
if (!$ok) {
throw new InvalidArgumentException('Unsupported CarbonPeriod argument: '.get_debug_type($argument));
}
}
$period = CarbonPeriod::create(...$arguments); Try / catch
try {
$period = CarbonPeriod::create(...$args);
} catch (\Carbon\Exceptions\InvalidPeriodParameterException $e) {
// surface as a 422 to the caller instead of a 500
throw new ValidationException('Invalid period parameters', 0, $e);
} Prevention
- Never forward unvalidated request data into create(...$params); coerce each value to a known type first
- Remember arrays must be spread: create(...$args) not create($args)
- Negative numbers, bools and arbitrary objects have no meaning to the constructor
When it happens
Trigger: new CarbonPeriod('garbage'); new CarbonPeriod(-1) (negative numbers have no slot); new CarbonPeriod(true); new CarbonPeriod(['2021-01-01', '2021-03-01']) passed as one array instead of spread; new CarbonPeriod($unrelatedObject).
Common situations: Forwarding unvalidated user input straight into create(...$params); a null-ish variable silently becoming a bool; forgetting to spread an array of prepared arguments; passing a value object instead of a DateTime.
Related errors
- Argument 1 passed to {$class}::{$method}() must be an instan
- Invalid ISO 8601 specification: {$iso}.
- $anchorDay parameter must not be set for $mode OverflowMode:
- You must specify $end or $recurrences but not both
- $name
AI-assisted analysis of briannesbitt/Carbon@b13f05955d (2026-08-17).
Data as JSON: /api/errors/b37994bb8227e27d.
Report an issue: GitHub.