octobercms/october · error · SystemException

Table name is required.

Error message

Table name is required.

What it means

ReportQueryBuilder::validate() runs before query construction and throws SystemException('Table name is required.') when the $tableName property is empty. The builder renders GROUP BY / aggregate SQL directly against this table name, so building a query without one is a programming/configuration error, not a data condition. The property is normally set via the builder's fluent table()/dataSource setup before buildQuery() is invoked.

Source

Thrown at modules/dashboard/classes/ReportQueryBuilder.php:661

            $result[$metric->getCode()] = $row->{$columnName};
        }

        return $result;
    }

    //
    // Internal Query Building
    //

    /**
     * validate ensures required properties are set
     *
     * @throws SystemException
     */
    protected function validate(): void
    {
        if (!$this->tableName) {
            throw new SystemException('Table name is required.');
        }

        if (!$this->dimension) {
            throw new SystemException('Dimension is required.');
        }

        if (($this->dateStart || $this->dateEnd) && $this->startTimestamp !== null) {
            throw new SystemException('Cannot use both date range and timestamp filtering.');
        }

        if (!$this->dateStart && $this->startTimestamp === null) {
            throw new SystemException('Either date range or start timestamp is required.');
        }

        if ($this->limit !== null && $this->pagination !== null) {
            throw new SystemException('Cannot use both limit and pagination.');
        }
    }

View on GitHub (pinned to b608633a7e)

Solutions

  1. Set the table before building: $builder->table('orders') (or ensure the data source definition provides the table name) so $tableName is non-empty when validate() runs.
  2. If you subclass ReportQueryBuilder, check you did not reset $tableName to '' or null in the subclass.
  3. Verify the data source's definition/tableName resolution logic returns a real table (log/dd the value just before build).
  4. Confirm the table exists in the database; if a migration renamed it, update the data source to the new name.

Example fix

// before
$builder = new ReportQueryBuilder;
$builder->setDimension($dim)->applyMetrics($metrics);
$data = $builder->buildQuery()->get();

// after
$builder = new ReportQueryBuilder;
$builder->table('orders')->setDimension($dim)->applyMetrics($metrics);
$data = $builder->buildQuery()->get();
Defensive patterns

Strategy: validation

Validate before calling

if (!strlen((string) $dataSource->getTableName())) {
    throw new InvalidArgumentException('Data source must define a table before querying.');
}
$builder->table($dataSource->getTableName());

Prevention

When it happens

Trigger: Creating a ReportQueryBuilder (or subclass) and calling a method that triggers buildQuery()/applySelect() without first setting the table — e.g. forgetting $builder->table('orders') or building from a data source whose tableName/columns definition returns an empty string; subclass overriding the property default with ''.

Common situations: Custom report data source that forgets to declare its table in the definition array; refactoring a builder setup method and dropping the table() call; database table renamed in a migration but the data source definition still points at nothing/empty.

Related errors


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