{"record":{"id":"e6c34bff96c5b265","repo":"octobercms/october","slug":"dimension-is-required","errorCode":null,"errorMessage":"Dimension is required.","messagePattern":"Dimension is required\\.","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/classes/ReportQueryBuilder.php","lineNumber":665,"sourceCode":"    }\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    }\n\n    /**\n     * buildQuery constructs the query builder\n     *","sourceCodeStart":647,"sourceCodeEnd":683,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/classes/ReportQueryBuilder.php#L647-L683","documentation":"ReportQueryBuilder::validate() requires a dimension to be set and throws SystemException('Dimension is required.') when $this->dimension is falsy. The dimension is the axis the report groups by (a ReportDimension instance), and every SELECT/GROUP BY expression the builder renders depends on it, so a dimensionless report query cannot be constructed. It is the second guard in validate(), checked right after the table name.","triggerScenarios":"Building a query via ReportQueryBuilder without calling setDimension()/dimension() — e.g. only applying metrics; passing null because the dimension lookup (findDimensionByCode on the data source) failed silently upstream; widget config that omits the 'dimension' key when composing the builder.","commonSituations":"Dashboard widget configuration missing or misspelling the dimension code so the controller resolves null and forwards it; reordering builder setup code so buildQuery() runs before the dimension is attached; data source that defines metrics but no default dimension.","solutions":["Set a dimension before building: $builder->setDimension($dataSource->getDimension('status')) using a code the data source actually defines.","If the dimension comes from widget/request config, validate the code resolves to a ReportDimension and fail with a clear message or default before calling the builder.","Fix the dashboard/widget definition to include a valid dimension code (check spelling/case against the data source's defineDimensions()).","In custom data sources, ensure getDimension()/findDimensionByCode covers the code your UI sends."],"exampleFix":"// before\n$builder->table('orders')->applyMetrics($metrics);\n$rows = $builder->buildQuery()->get();\n\n// after\n$dimension = $dataSource->findDimensionByCode('status');\nif (!$dimension) {\n    throw new ApplicationException('Unknown dimension: status');\n}\n$builder->table('orders')->setDimension($dimension)->applyMetrics($metrics);\n$rows = $builder->buildQuery()->get();","handlingStrategy":"validation","validationCode":"$dimension = $dataSource->findDimensionByCode($code);\nif (!$dimension instanceof ReportDimension) {\n    throw new InvalidArgumentException(\"Unknown dimension '{$code}' on this data source.\");\n}\n$builder->setDimension($dimension);","typeGuard":"function resolveDimension(ReportDataSourceBase $source, string $code): ?ReportDimension\n{\n    foreach ($source->getAvailableDimensions() as $dimension) {\n        if ($dimension->getCode() === $code) {\n            return $dimension;\n        }\n    }\n    return null;\n}","tryCatchPattern":null,"preventionTips":["Validate dimension codes from widget/request payloads against the data source before configuring the builder.","Keep dimension codes consistent between front-end selectors and data source definitions (case-sensitive).","Fail with a descriptive application error when a dimension cannot be resolved instead of passing null downstream."],"tags":["dashboard","report-query-builder","dimension","validation"],"backgroundTag":"required-builder-property-missing","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}