{"record":{"id":"6bb9c6bb09092583","repo":"octobercms/october","slug":"table-name-is-required","errorCode":null,"errorMessage":"Table name is required.","messagePattern":"Table name is required\\.","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/classes/ReportQueryBuilder.php","lineNumber":661,"sourceCode":"            $result[$metric->getCode()] = $row->{$columnName};\n        }\n\n        return $result;\n    }\n\n    //\n    // Internal Query Building\n    //\n\n    /**\n     * validate ensures required properties are set\n     *\n     * @throws SystemException\n     */\n    protected function validate(): void\n    {\n        if (!$this->tableName) {\n            throw new SystemException('Table name is required.');\n        }\n\n        if (!$this->dimension) {\n            throw new SystemException('Dimension is required.');\n        }\n\n        if (($this->dateStart || $this->dateEnd) && $this->startTimestamp !== null) {\n            throw new SystemException('Cannot use both date range and timestamp filtering.');\n        }\n\n        if (!$this->dateStart && $this->startTimestamp === null) {\n            throw new SystemException('Either date range or start timestamp is required.');\n        }\n\n        if ($this->limit !== null && $this->pagination !== null) {\n            throw new SystemException('Cannot use both limit and pagination.');\n        }\n    }","sourceCodeStart":643,"sourceCodeEnd":679,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/classes/ReportQueryBuilder.php#L643-L679","documentation":"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.","triggerScenarios":"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 ''.","commonSituations":"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.","solutions":["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.","If you subclass ReportQueryBuilder, check you did not reset $tableName to '' or null in the subclass.","Verify the data source's definition/tableName resolution logic returns a real table (log/dd the value just before build).","Confirm the table exists in the database; if a migration renamed it, update the data source to the new name."],"exampleFix":"// before\n$builder = new ReportQueryBuilder;\n$builder->setDimension($dim)->applyMetrics($metrics);\n$data = $builder->buildQuery()->get();\n\n// after\n$builder = new ReportQueryBuilder;\n$builder->table('orders')->setDimension($dim)->applyMetrics($metrics);\n$data = $builder->buildQuery()->get();","handlingStrategy":"validation","validationCode":"if (!strlen((string) $dataSource->getTableName())) {\n    throw new InvalidArgumentException('Data source must define a table before querying.');\n}\n$builder->table($dataSource->getTableName());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure the builder fully (table, dimension, time filter) before triggering build; keep setup in one method.","Assert required properties in a single pre-build checklist in your own wrapper around ReportQueryBuilder.","Cover each data source with an integration test that builds one query — this catches missing table definitions early."],"tags":["dashboard","report-query-builder","validation","sql"],"backgroundTag":"required-builder-property-missing","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}