{"record":{"id":"c2746bc6870fd082","repo":"octobercms/october","slug":"unknown-widget-report-interval-widgetinterval","errorCode":null,"errorMessage":"Unknown widget report interval {$widgetInterval}","messagePattern":"Unknown widget report interval (.+?)","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/classes/ReportFetchData.php","lineNumber":233,"sourceCode":"                break;\n            case Dash::INTERVAL_TYPE_MONTH:\n                $dateStart = Carbon::now()->startOfMonth();\n                break;\n            case Dash::INTERVAL_TYPE_WEEK:\n                $dateStart = Carbon::now()->startOfWeek(Carbon::MONDAY); // TODO\n                break;\n            case Dash::INTERVAL_TYPE_HOUR:\n                $dateEnd = null;\n                $startTimestamp = time() - 3600;\n                break;\n            case Dash::INTERVAL_TYPE_DAYS:\n                $days = isset($this->widgetConfig['date_interval_days'])\n                    ? $this->widgetConfig['date_interval_days']\n                    : 1;\n                $dateStart = Carbon::now()->subDays($days - 1);\n                break;\n            default:\n                throw new SystemException(\"Unknown widget report interval {$widgetInterval}\");\n        }\n\n        return [\n            $dateStart,\n            $dateEnd,\n            $startTimestamp\n        ];\n    }\n\n    /**\n     * parseDashboardDate safely parses a dashboard date from the browser.\n     */\n    protected function parseDashboardDate(?string $value): ?Carbon\n    {\n        $value = trim((string) $value);\n        if ($value === '') {\n            return null;\n        }","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/classes/ReportFetchData.php#L215-L251","documentation":"ReportFetchData::getRequestedDateInterval() maps the widget configuration key 'date_interval' onto the Dash::INTERVAL_TYPE_* constants ('dashboard', 'year', 'quarter', 'month', 'week', 'days', 'hour' — 'days' additionally reads 'date_interval_days'). When the config value matches none of them, the switch default throws, embedding the offending value.","triggerScenarios":"A widget whose persisted config contains date_interval = 'day' (singular typo), 'last-30-days', or a value written by an older module version — anything not in Dash::INTERVAL_TYPE_*. Note: when the key is absent the code defaults to INTERVAL_TYPE_DASHBOARD and does not throw.","commonSituations":"Widget records in system_widget_data created by an older version of the dashboard module, hand-edited widget config JSON, or DB restores across plugin versions that changed the interval vocabulary.","solutions":["Open the widget's settings in the dashboard UI and re-select a supported interval, then save — this rewrites the config","Directly fix the stored config: UPDATE the widget data so date_interval is one of Dash::INTERVAL_TYPE_* ('dashboard', 'year', 'quarter', 'month', 'week', 'days', 'hour')","Delete the stale widget record and re-create the widget if its config cannot be repaired","After upgrading the dashboard module, audit existing widget configs for removed interval values"],"exampleFix":"// before (persisted widget config)\n{\"date_interval\": \"day\", \"date_interval_days\": 30}\n\n// after\n{\"date_interval\": \"days\", \"date_interval_days\": 30}","handlingStrategy":"try-catch","validationCode":"$knownIntervals = [\n    Dash::INTERVAL_TYPE_DASHBOARD,\n    Dash::INTERVAL_TYPE_YEAR,\n    Dash::INTERVAL_TYPE_QUARTER,\n    Dash::INTERVAL_TYPE_MONTH,\n    Dash::INTERVAL_TYPE_WEEK,\n    Dash::INTERVAL_TYPE_DAYS,\n    Dash::INTERVAL_TYPE_HOUR,\n];\n$interval = $widgetConfig['date_interval'] ?? Dash::INTERVAL_TYPE_DASHBOARD;\nif (!in_array($interval, $knownIntervals, true)) {\n    // repair stale config before it reaches ReportFetchData\n    $widgetConfig['date_interval'] = Dash::INTERVAL_TYPE_DASHBOARD;\n}","typeGuard":"function isKnownWidgetInterval(string $interval): bool\n{\n    return in_array($interval, [\n        Dash::INTERVAL_TYPE_DASHBOARD,\n        Dash::INTERVAL_TYPE_YEAR,\n        Dash::INTERVAL_TYPE_QUARTER,\n        Dash::INTERVAL_TYPE_MONTH,\n        Dash::INTERVAL_TYPE_WEEK,\n        Dash::INTERVAL_TYPE_DAYS,\n        Dash::INTERVAL_TYPE_HOUR,\n    ], true);\n}","tryCatchPattern":"try {\n    $fetchData = new ReportFetchData($dataSource, $widgetConfig, $extraData);\n} catch (SystemException $e) {\n    // stale widget config — reset the interval and retry once with a safe default\n    $widgetConfig['date_interval'] = Dash::INTERVAL_TYPE_DASHBOARD;\n    $fetchData = new ReportFetchData($dataSource, $widgetConfig, $extraData);\n}","preventionTips":["Never hand-edit widget config JSON for intervals — change them through the widget settings UI","After upgrading the dashboard module, audit persisted widget configs for removed/renamed interval values","Write new interval values using the Dash::INTERVAL_TYPE_* constants"],"tags":["php","dashboard","report","widget","date-interval","config"],"backgroundTag":"invalid-config-value","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}