flarum/framework · error · InvalidParameterException

A custom date range must be specified

Error message

A custom date range must be specified

What it means

Input validation guard in the statistics API controller. When period=custom, getResponse expects a dateRange query parameter array with 'start' and 'end' values; the request declared a custom reporting period but supplied no usable custom date range, so the required bounds are absent.

Solutions

  1. Supply dateRange[start] and dateRange[end] (unix timestamps) whenever period=custom.
  2. Choose a non-custom period (e.g. lifetime, or a fixed reporting period) so no date range is required.
  3. Validate the range client-side before submitting the request.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at extensions/statistics/src/Api/Controller/ShowStatisticsData.php:87 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15). Data as JSON: /api/errors/3ba8159ece520b3f. Report an issue: GitHub.

Appendix: source

Thrown at extensions/statistics/src/Api/Controller/ShowStatisticsData.php:87

        return new JsonResponse($this->getResponse($model, $reportingPeriod, $customDateRange));
    }

    private function getResponse(?string $model, ?string $period, ?array $customDateRange): array
    {
        if ($period === 'lifetime') {
            return $this->getLifetimeStatistics();
        }

        if (! Arr::exists($this->entities, $model)) {
            throw new InvalidParameterException('A model must be specified');
        }

        if ($period === 'custom') {
            $start = (int) $customDateRange['start'];
            $end = (int) $customDateRange['end'];

            if (! $customDateRange || ! $start || ! $end) {
                throw new InvalidParameterException('A custom date range must be specified');
            }

            // Seconds-based timestamps
            $startRange = Carbon::createFromTimestampUTC($start)->toDateTime();
            $endRange = Carbon::createFromTimestampUTC($end)->toDateTime();

            // We can't really cache this
            return $this->getTimedCounts($this->entities[$model][0], $this->entities[$model][1], $startRange, $endRange);
        }

        return $this->getTimedStatistics($model);
    }

    private function getLifetimeStatistics(): array
    {
        return $this->cache->remember('flarum-subscriptions.lifetime_stats', self::$lifetimeStatsCacheTtl, function () {
            return array_map(function ($entity) {
                return $entity[0]->count();

View on GitHub (pinned to 4b939f6853)