{"record":{"id":"f109f1b0dbf27237","repo":"octobercms/october","slug":"report-widget-data-source-class-is-not-set","errorCode":null,"errorMessage":"Report widget data source class is not set","messagePattern":"Report widget data source class is not set","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/widgets/dash/HasWidgetData.php","lineNumber":286,"sourceCode":"    private function getDataSourceDimensionAndFields(ReportDataSourceBase $dataSource, string $dimensionCode): array\n    {\n        $result = [];\n\n        $dimension = $this->findDimension($dataSource, $dimensionCode, false);\n        if ($dimension) {\n            $result[$dimension->getDataSetColumName()] = Lang::get($dimension->getDisplayName());\n        }\n\n        return $result;\n    }\n\n    /**\n     * getRequestedDataSource\n     */\n    protected function getRequestedDataSource(array $widgetConfig): ReportDataSourceBase\n    {\n        if (!isset($widgetConfig['dataSource'])) {\n            throw new SystemException('Report widget data source class is not set');\n        }\n\n        return $this->makeDataSource($widgetConfig['dataSource']);\n    }\n}\n","sourceCodeStart":268,"sourceCodeEnd":292,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/widgets/dash/HasWidgetData.php#L268-L292","documentation":"HasWidgetData::getRequestedDataSource extracts the data source for a report widget request. It requires the widgetConfig array to contain a dataSource key; without it, a SystemException is thrown before DashManager is asked for the source. Report widgets bound to data sources must always carry dataSource in their configuration.","triggerScenarios":"Loading dimension/metric data for a report widget whose config lacks dataSource; hand-built widget_config in AJAX payloads that only includes type and dimension; a saved dashboard definition where the dataSource property was dropped during editing or migration.","commonSituations":"Manually constructing widget configs in custom code instead of using the default configs from DashManager::getDefaultWidgetConfigs(); definitions edited in the database; older definitions created before dataSource became required.","solutions":["Add dataSource: <fully qualified registered data source class> to the widget configuration.","Recreate the widget through the dashboard UI so the default config (which includes dataSource) is applied.","Validate saved definitions on load and reject/repair entries missing dataSource.","Confirm the value is the class registered with registerDataSourceClass, not a display name."],"exampleFix":"// before\n$widgetConfig = ['type' => 'sum', 'dimension' => 'orders'];\n\n// after\n$widgetConfig = ['type' => 'sum', 'dimension' => 'orders', 'dataSource' => 'MyPlugin\\Report\\OrdersDataSource'];","handlingStrategy":"validation","validationCode":"if (empty($widgetConfig['dataSource']) || !is_string($widgetConfig['dataSource'])) {\n    throw new \\ValidationException(['dataSource' => 'A registered data source class is required']);\n}","typeGuard":null,"tryCatchPattern":"try {\n    $source = $this->getRequestedDataSource($widgetConfig);\n} catch (\\SystemException $e) {\n    \\Log::warning('Widget missing dataSource: '.json_encode($widgetConfig));\n    return null;\n}","preventionTips":["Generate widget configs from DashManager::getDefaultWidgetConfigs() so dataSource is always set.","Reject definition imports that lack dataSource.","Treat missing dataSource as a data bug and repair the saved definition at load time."],"tags":["dashboard","datasource","config","missing-key"],"backgroundTag":"missing-config-key","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}