{"record":{"id":"45f45ae36c622b3b","repo":"octobercms/october","slug":"the-display-name-cannot-be-empty-45f45a","errorCode":null,"errorMessage":"The display name cannot be empty.","messagePattern":"The display name cannot be empty\\.","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/classes/ReportMetric.php","lineNumber":74,"sourceCode":"     * @param ?array $intlFormatOptions Client-side formatting options, compatible with the Intl.NumberFormat() constructor options argument.\n     * Skip the argument to use the default formatting options.\n     */\n    public function __construct(string $code, string $databaseColumnName, string $displayName, string $aggregateFunction, ?array $intlFormatOptions = null)\n    {\n        if (!strlen($code)) {\n            throw new SystemException('The metric code cannot be empty.');\n        }\n\n        if (!preg_match('/^[a-z][a-z0-9_]+$/i', $code)) {\n            throw new SystemException('The metric code can only contain Latin letters, numbers and underscore. The first character must be a letter');\n        }\n\n        if (!strlen($databaseColumnName)) {\n            throw new SystemException('The database column name cannot be empty.');\n        }\n\n        if (!strlen($displayName)) {\n            throw new SystemException('The display name cannot be empty.');\n        }\n\n        if (!strlen($aggregateFunction)) {\n            throw new SystemException('The aggregate function cannot be empty.');\n        }\n\n        $knownAggregateFunctions = [\n            self::AGGREGATE_SUM,\n            self::AGGREGATE_AVG,\n            self::AGGREGATE_MIN,\n            self::AGGREGATE_MAX,\n            self::AGGREGATE_COUNT,\n            self::AGGREGATE_NONE,\n            self::AGGREGATE_COUNT_DISTINCT,\n            self::AGGREGATE_COUNT_DISTINCT_NOT_NULL\n        ];\n\n        if (!in_array($aggregateFunction, $knownAggregateFunctions)) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/classes/ReportMetric.php#L56-L92","documentation":"The ReportMetric constructor requires a non-empty human-readable $displayName and throws SystemException when strlen($displayName) is 0. The display name is what the dashboard UI shows for the metric in widget headers, tables and charts, so an empty label breaks rendering. Like the other constructor guards, this fails fast at data-source definition time instead of producing a half-configured metric later. Only '' triggers it; '0' passes.","triggerScenarios":"Calling `new ReportMetric($code, $column, '', 'avg')` — typically the 3rd argument is forgotten when developers copy a shorter constructor call, or a localization helper (e.g. __() on a missing lang key returning '') yields an empty string.","commonSituations":"Adding a new metric in a hurry and skipping the label; passing a translation key that does not exist in the lang file so the __() call returns empty; building metrics from a config array missing the 'label'/'name' key.","solutions":["Supply a non-empty display string as the 3rd argument, e.g. new ReportMetric('avg_rating', 'rating', 'Average rating', ReportMetric::AGGREGATE_AVG).","If using localization, make sure the lang key exists and __() returns a real string (check the lang file for typos in the key).","Add the missing 'label' key to the metric definition array when metrics are config-driven.","When localizing, guard empty translations during development: $label = __($key) ?: ucfirst(str_replace('_', ' ', $code));"],"exampleFix":"// before\nnew ReportMetric('avg_rating', 'rating', '', ReportMetric::AGGREGATE_AVG);\n\n// after\nnew ReportMetric('avg_rating', 'rating', 'Average rating', ReportMetric::AGGREGATE_AVG);","handlingStrategy":"validation","validationCode":"$label = __($langKey) ?: ucfirst(str_replace('_', ' ', $code));\nif (!strlen($label)) {\n    $label = ucfirst($code);\n}\n$metric = new ReportMetric($code, $column, $label, $aggregate);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give every metric a human label at authoring time; never leave the third argument blank.","When using __() for localized labels, verify the lang key exists — missing keys can return an empty string.","Include label presence in config schema validation for data sources."],"tags":["dashboard","report-metric","constructor-validation","localization"],"backgroundTag":"constructor-argument-validation","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}