{"record":{"id":"b3e5c42b75d591a9","repo":"octobercms/october","slug":"the-metric-code-cannot-be-empty","errorCode":null,"errorMessage":"The metric code cannot be empty.","messagePattern":"The metric code cannot be empty\\.","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/classes/ReportMetric.php","lineNumber":62,"sourceCode":"\n    /**\n     * @var ?callable Server-side formatter for human-readable display values.\n     */\n    private $displayFormatter;\n\n    /**\n     * __construct a new metric instance.\n     * @param string $code Specifies the metric referral code.\n     * @param string $databaseColumnName Specifies the column name in the data source table.\n     * @param string $displayName Specifies the metric name used in reports.\n     * @param string $aggregateFunction Specifies the aggregate function for the metric.\n     * @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","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/classes/ReportMetric.php#L44-L80","documentation":"ReportMetric's constructor requires a non-empty metric code, since the code identifies the metric in widget configurations, fetch requests, and cache keys. An empty string throws before any other validation of the metric definition.","triggerScenarios":"new ReportMetric('', 'oc_amount', 'Total', 'sum') — any construction where the first argument has zero length.","commonSituations":"Config-driven metric lists where a 'code' key is missing or resolves to ''; copy-paste metric definitions left with an empty placeholder; whitespace-only codes (' ' passes strlen but fails the following regex, so trim first).","solutions":["Ensure every metric definition carries a unique non-empty code (e.g. 'total', 'avg_order')","Validate config-derived codes with trim() !== '' before constructing metrics","Fail loudly at config load time so bad definitions are caught during development, not at render time"],"exampleFix":"// before\n$metric = new ReportMetric($config['code'] ?? '', 'oc_amount', 'Total', 'sum');\n\n// after\n$code = trim((string) ($config['code'] ?? ''));\nif ($code === '') {\n    throw new InvalidArgumentException('Metric code missing in config for metric: ' . ($config['name'] ?? '?'));\n}\n$metric = new ReportMetric($code, 'oc_amount', 'Total', 'sum');","handlingStrategy":"validation","validationCode":"$code = trim((string) ($config['code'] ?? ''));\nif ($code === '') {\n    throw new InvalidArgumentException('Metric code missing for metric: ' . ($config['name'] ?? '?'));\n}\n$metric = new ReportMetric($code, $config['column'], $config['name'], $config['aggregate']);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Define metric codes in one place (config/entity) and validate presence at load time","Remember the constructor also validates column, display name, and aggregate function — check all four","Use meaningful codes ('total', 'avg_order') since they become the API contract for fetch requests"],"tags":["php","dashboard","report","metric","validation"],"backgroundTag":"empty-required-argument","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}