octobercms/october · error · SystemException

The provided class is not a report data source:

Error message

The provided class is not a report data source: 

What it means

HasDataSources::getDataSource(string $className) only instantiates classes that were previously registered in the manager's $dataSources array; the method then double-checks is_subclass_of($className, ReportDataSourceBase::class) and throws SystemException('The provided class is not a report data source: <class>') if the registered entry is not a ReportDataSourceBase subclass. Because registration happens via registerDataSource, this fires when a plugin registered a non-data-source class (or the class changed parent) — not when the class is merely unknown (unknown returns null).

Source

Thrown at modules/dashboard/classes/dashmanager/HasDataSources.php:46

        $this->dataSources[$className] = [
            'displayName' => $displayName
        ];
    }

    /**
     * getDataSource returns a data source instance by its class name.
     * @throws SystemException if the provided class name is not a subclass Dashboard\Classes\ReportDataSourceBase.
     * @param string $className A data source class name.
     * @return ?ReportDataSourceBase Returns the data source instance or null.
     */
    public function getDataSource(string $className): ?ReportDataSourceBase
    {
        if (!array_key_exists($className, $this->dataSources)) {
            return null;
        }

        if (!is_subclass_of($className, ReportDataSourceBase::class)) {
            throw new SystemException("The provided class is not a report data source: " . $className);
        }

        return new $className();
    }

    /**
     * listDataSourceClasses returns class and display names of registered data sources.
     * @return array
     */
    public function listDataSourceClasses(): array
    {
        $result = [];
        foreach ($this->dataSources as $className => $info) {
            $result[$className] = $info['displayName'];
        }
        return $result;
    }

View on GitHub (pinned to b608633a7e)

Solutions

  1. Make the registered class extend Dashboard\Classes\ReportDataSourceBase and implement its abstract members (defineColumns/defineMetrics etc.).
  2. Fix the class string passed to registerDataSource() to reference the intended, existing data source class.
  3. Only register data sources at plugin boot (Plugin::boot / registerDashboards) and remove stray registrations of helpers or models.
  4. Check parent class changes after upgrading the dashboard module and restore the correct base class.

Example fix

// before
$manager->registerDataSource(\MyPlugin\Classes\OrderHelper::class);
$manager->getDataSource(\MyPlugin\Classes\OrderHelper::class); // throws

// after
class OrdersDataSource extends \Dashboard\Classes\ReportDataSourceBase { /* ... */ }
$manager->registerDataSource(OrdersDataSource::class);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!class_exists($className) || !is_subclass_of($className, ReportDataSourceBase::class)) {
    throw new InvalidArgumentException("{$className} is not a report data source.");
}
$source = $manager->getDataSource($className);

Type guard

function isReportDataSourceClass(mixed $class): bool
{
    return is_string($class) && class_exists($class) && is_subclass_of($class, ReportDataSourceBase::class);
}

Try / catch

try {
    $source = $manager->getDataSource($className);
} catch (SystemException $e) {
    Log::error($e->getMessage());
    // skip misregistered source, continue with remaining dashboards
    $source = null;
}

Prevention

When it happens

Trigger: Calling DashManager's registerDataSource with a plain class, an interface name, or a class that extends something else, then getDataSource($thatClass); refactoring a data source to no longer extend ReportDataSourceBase while leaving it registered; registering a string that resolves to a trait or abstract helper.

Common situations: Plugin boot code copy-pasted with the wrong class name into registerDataSource(); inheritance changed during an upgrade (class now extends a different base); typo in the namespace making is_subclass_of fail.

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/39afcaac427eaf4f. Report an issue: GitHub.