{"record":{"id":"b5b4ced59ad1047c","repo":"octobercms/october","slug":"current-page-is-not-set-for-a-paginated-query","errorCode":null,"errorMessage":"Current page is not set for a paginated query","messagePattern":"Current page is not set for a paginated query","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/classes/ReportFetchData.php","lineNumber":327,"sourceCode":"            return new ReportDataOrderRule(ReportDataOrderRule::ATTR_TYPE_DIMENSION);\n        }\n\n        $sortBy = $this->widgetConfig['sortBy'];\n        $sortOrder = $this->widgetConfig['sortOrder'];\n        return ReportDataOrderRule::createFromWidgetConfig($sortOrder, $sortBy);\n    }\n\n    /**\n     * getRequestedPaginationParams\n     */\n    protected function getRequestedPaginationParams(): ?ReportDataPaginationParams\n    {\n        if (empty($this->widgetConfig['records_per_page'])) {\n            return null;\n        }\n\n        if (!array_key_exists('current_page', $this->extraData)) {\n            throw new SystemException('Current page is not set for a paginated query');\n        }\n\n        return new ReportDataPaginationParams(\n            (int) $this->widgetConfig['records_per_page'],\n            (int) $this->extraData['current_page']\n        );\n    }\n\n    /**\n     * getRequestedMetricsConfiguration\n     */\n    protected function getRequestedMetricsConfiguration(): array\n    {\n        if (!$this->metricCodes) {\n            return [];\n        }\n\n        $result = [];","sourceCodeStart":309,"sourceCodeEnd":345,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/classes/ReportFetchData.php#L309-L345","documentation":"When a widget's configuration has a non-empty 'records_per_page', ReportFetchData builds pagination parameters and requires the request to supply the current page. getRequestedPaginationParams() throws when the 'current_page' key is absent from the fetch request's extraData.","triggerScenarios":"A fetch request against a widget configured with records_per_page = 20 whose AJAX payload lacks current_page — e.g. a custom client that only sends filters/metrics, or a first load path that calls the handler without page information.","commonSituations":"Enabling pagination in widget config without updating the front-end to always send the page; integrating the dashboard data API from external scripts that mimic the payload incompletely; upgrades that added pagination to existing widgets.","solutions":["Always include current_page (1-based integer) in the fetch request when the widget has records_per_page set","Clear the records_per_page value in the widget configuration to disable pagination if the front-end cannot send the page","When proxying requests, default the value server-side: $extraData['current_page'] = $extraData['current_page'] ?? 1 before invoking the handler"],"exampleFix":"// before\n$handler->onFetchData([\n    'metrics' => ['total'],\n]);\n\n// after\n$handler->onFetchData([\n    'metrics' => ['total'],\n    'current_page' => 1,\n]);","handlingStrategy":"validation","validationCode":"// client side: always send the page for paginated widgets\n$extraData['current_page'] = max(1, (int) ($extraData['current_page'] ?? 1));\n\n// server side: default the page before invoking the fetch handler\n$this->extraData['current_page'] = $this->extraData['current_page'] ?? 1;","typeGuard":"function hasRequiredPaginationParams(array $widgetConfig, array $extraData): bool\n{\n    if (empty($widgetConfig['records_per_page'])) {\n        return true; // pagination disabled, no page required\n    }\n    return array_key_exists('current_page', $extraData);\n}","tryCatchPattern":"try {\n    $result = $widget->onFetchData($extraData);\n} catch (SystemException $e) {\n    if (str_contains($e->getMessage(), 'Current page is not set')) {\n        $extraData['current_page'] = 1;\n        return $widget->onFetchData($extraData);\n    }\n    throw $e;\n}","preventionTips":["Whenever records_per_page is configured, make the front-end always submit current_page (1-based)","At API proxies, default current_page to 1 before calling the handler","Disabling pagination (clear records_per_page) also removes the requirement"],"tags":["php","dashboard","report","pagination","fetch","request-parameter"],"backgroundTag":"missing-request-parameter","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}