briannesbitt/Carbon · error · EndLessPeriodException

Endless period can't be converted to array nor counted.

Error message

Endless period can't be converted to array nor counted.

What it means

toArray() — and count(), which delegates to it — must materialize every date at once. isUnfilteredAndEndLess() (src/Carbon/CarbonPeriod.php:1652) returns true when the period has no custom filter and no finite bound: no recurrences filter at all, INF recurrences, or an end that is null/end-of-time. Materializing such a period would never terminate, so EndLessPeriodException is thrown instead (src/Carbon/CarbonPeriod.php:1686).

Source

Thrown at src/Carbon/CarbonPeriod.php:1686

                    break;

                default:
                    return false;
            }
        }

        return true;
    }

    /**
     * Convert the date period into an array without changing current iteration state.
     *
     * @return CarbonInterface[]
     */
    public function toArray(): array
    {
        if ($this->isUnfilteredAndEndLess()) {
            throw new EndLessPeriodException("Endless period can't be converted to array nor counted.");
        }

        $state = [
            $this->key,
            $this->carbonCurrent ? $this->carbonCurrent->avoidMutation() : null,
            $this->validationResult,
        ];

        $result = iterator_to_array($this);

        [$this->key, $this->carbonCurrent, $this->validationResult] = $state;

        return $result;
    }

    /**
     * Count dates in the date period.
     */

View on GitHub (pinned to b13f05955d)

Solutions

  1. Bound the period before materializing: ->setRecurrences(30) or ->setEndDate($date)
  2. Iterate lazily with foreach and stop at your own limit instead of calling toArray()
  3. Check first: if ($period->isUnfilteredAndEndLess()) handle the infinite case explicitly (e.g. paginate by date windows)

Example fix

// before
$dates = CarbonPeriod::create('2021-01-01')->toArray(); // endless

// after
$dates = CarbonPeriod::create('2021-01-01')
    ->setEndDate('2021-01-31')
    ->toArray();
// or iterate lazily with an own limit
$i = 0;
foreach (CarbonPeriod::create('2021-01-01') as $date) {
    if (++$i > 30) break;
}
Defensive patterns

Strategy: validation

Validate before calling

if ($period->isUnfilteredAndEndLess()) {
    throw new InvalidArgumentException('Refusing to materialize an endless period');
}
$count = $period->count();

Try / catch

try {
    $dates = $period->toArray();
} catch (\Carbon\Exceptions\EndLessPeriodException $e) {
    $dates = iterator_to_array(new \LimitIterator($period->getIterator(), 0, 100));
}

Prevention

When it happens

Trigger: CarbonPeriod::create('2021-01-01')->toArray(); CarbonPeriod::days(1)->count(); CarbonPeriod::create()->setRecurrences(INF)->toArray(); any period built with only a start (and the default P1D interval) then passed to count()/toArray()/iterator_to_array().

Common situations: Fluent building like CarbonPeriod::days(1) that looks complete but is unbounded, later hitting defensive count()/toArray() calls; generic code that counts results for logging/pagination; forgetting that an omitted end date means 'forever'.

Related errors


AI-assisted analysis of briannesbitt/Carbon@b13f05955d (2026-08-17). Data as JSON: /api/errors/4cb17748943b2c10. Report an issue: GitHub.