octobercms/october · error · SystemException

The database column name cannot be empty.

Error message

The database column name cannot be empty.

What it means

ReportMetric's constructor validates every argument and throws SystemException when the $databaseColumnName string is empty. ReportMetric describes one measurable column of a report data source (e.g. total orders, avg rating), and the database column name is what gets injected into SQL aggregate expressions, so an empty value would produce an invalid query. The check uses strlen(), so '' (or an unset default) triggers it while '0' is accepted. It is a fail-fast guard meant to catch misconfigured data source definitions, not a runtime condition.

Source

Thrown at modules/dashboard/classes/ReportMetric.php:70

     * @param string $code Specifies the metric referral code.
     * @param string $databaseColumnName Specifies the column name in the data source table.
     * @param string $displayName Specifies the metric name used in reports.
     * @param string $aggregateFunction Specifies the aggregate function for the metric.
     * @param ?array $intlFormatOptions Client-side formatting options, compatible with the Intl.NumberFormat() constructor options argument.
     * Skip the argument to use the default formatting options.
     */
    public function __construct(string $code, string $databaseColumnName, string $displayName, string $aggregateFunction, ?array $intlFormatOptions = null)
    {
        if (!strlen($code)) {
            throw new SystemException('The metric code cannot be empty.');
        }

        if (!preg_match('/^[a-z][a-z0-9_]+$/i', $code)) {
            throw new SystemException('The metric code can only contain Latin letters, numbers and underscore. The first character must be a letter');
        }

        if (!strlen($databaseColumnName)) {
            throw new SystemException('The database column name cannot be empty.');
        }

        if (!strlen($displayName)) {
            throw new SystemException('The display name cannot be empty.');
        }

        if (!strlen($aggregateFunction)) {
            throw new SystemException('The aggregate function cannot be empty.');
        }

        $knownAggregateFunctions = [
            self::AGGREGATE_SUM,
            self::AGGREGATE_AVG,
            self::AGGREGATE_MIN,
            self::AGGREGATE_MAX,
            self::AGGREGATE_COUNT,
            self::AGGREGATE_NONE,
            self::AGGREGATE_COUNT_DISTINCT,

View on GitHub (pinned to b608633a7e)

Solutions

  1. Pass the real, existing database column name as the 2nd constructor argument, e.g. new ReportMetric('total_orders', 'total_order_amount', 'Total orders', ReportMetric::AGGREGATE_SUM).
  2. If the metric is config-driven, add/fix the missing column key in the dashboard/data source configuration before constructing the metric.
  3. For computed metrics with no single column, aggregate an expression-safe column or use count(*) semantics via AGGREGATE_COUNT on a not-null column instead of passing ''.
  4. Verify the column exists in the underlying table with SHOW COLUMNS / describe to rule out a rename mismatch.

Example fix

// before
new ReportMetric('orders', '', 'Orders', ReportMetric::AGGREGATE_SUM);

// after
new ReportMetric('orders', 'order_id', 'Orders', ReportMetric::AGGREGATE_COUNT);
Defensive patterns

Strategy: validation

Validate before calling

$column = $config['columnName'] ?? '';
if (!strlen($column)) {
    throw new InvalidArgumentException("Metric '{$config['code']}' is missing a database column.");
}
$metric = new ReportMetric($config['code'], $column, $config['label'], $config['aggregate']);

Prevention

When it happens

Trigger: Calling `new ReportMetric($code, '', $displayName, 'sum')` (or omitting/falsy-defaulting the second constructor argument) inside a data source's defineMetrics()/getAvailableMetrics() implementation. Also instantiating ReportMetric from array/YAML config where the 'columnName' key is missing and read with a '' default.

Common situations: Authoring a custom report data source and forgetting to map a metric to a real table column; renaming a DB column but not the data source definition; generating metrics in a loop from a config array where one entry lacks the column key.

Related errors


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