{"record":{"id":"b4bdeb2b173c6a52","repo":"octobercms/october","slug":"unknown-metric","errorCode":null,"errorMessage":"Unknown metric: ","messagePattern":"Unknown metric: ","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/dashboard/classes/ReportMetric.php","lineNumber":216,"sourceCode":"        if (!count($metric)) {\n            return null;\n        }\n\n        return end($metric);\n    }\n\n    /**\n     * Finds a metric by its code. Throws an exception if the metric is not found.\n     * @param ReportMetric[] $availableMetrics\n     * @param string $metricCode\n     * @param bool $throw Throw exception if the metric doesn't exist.\n     * @return ?ReportMetric\n     */\n    public static function findMetricByCodeStrict(array $availableMetrics, string $metricCode, $throw = true): ?ReportMetric\n    {\n        $metric = self::findMetricByCode($availableMetrics, $metricCode);\n        if (!$metric && $throw) {\n            throw new SystemException('Unknown metric: '.$metricCode);\n        }\n\n        return $metric;\n    }\n\n    /**\n     * Returns code unique for this metric to be used as a part of a cache key.\n     * @return string\n     */\n    public function getCacheUniqueCode(): string\n    {\n        return $this->getCode() . $this->getDatabaseColumnName() . $this->getAggregateFunction();\n    }\n\n    /**\n     * Returns a query column name corresponding to this metric.\n     * @return string\n     */","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/dashboard/classes/ReportMetric.php#L198-L234","documentation":"ReportMetric::findMetricByCodeStrict(array $availableMetrics, string $metricCode, bool $throw = true) looks up a metric by its unique code and, when not found and $throw is true, throws SystemException('Unknown metric: <code>'). Callers include Dash widget metric resolution, ReportDataSourceBase and ReportQueryBuilder (ordering by a metric). The error means the code string you referenced does not exist in the metric list the data source defines — usually a typo, a renamed code, or asking a data source for another source's metric.","triggerScenarios":"A dashboard/widget request or definition references metric code 'total_revenue' while the data source defines 'revenue'; ordering report data by a metric attribute whose code was never added via defineMetrics(); calling findMetricByCodeStrict($metrics, $code) where $metrics came from a different data source than the code belongs to.","commonSituations":"Renaming a metric code in a data source while stale dashboard definitions (stored per-user or in DB) still reference the old code; copy-pasting a widget config between data sources; case mismatch ('Revenue' vs 'revenue') — codes are case-sensitive because findMetricByCode compares getCode() === $metricCode.","solutions":["Open the data source class (defineMetrics()/getAvailableMetrics()) and align the referenced code with an existing metric code exactly, including case.","If the metric should exist, add it: new ReportMetric('total_revenue', ...) in the data source's metric list.","If stale dashboard definitions are the cause, update or reset the saved dashboard/widget configuration (Dashboard model) so it references current codes.","If absence is legitimate at runtime, call findMetricByCodeStrict($metrics, $code, false) to get null instead of an exception and handle it gracefully."],"exampleFix":"// before\n$metric = ReportMetric::findMetricByCodeStrict($dataSource->getAvailableMetrics(), 'total_revenue');\n\n// after (metric code fixed to what the source defines)\n$metric = ReportMetric::findMetricByCodeStrict($dataSource->getAvailableMetrics(), 'revenue');\n\n// after (tolerate absence)\n$metric = ReportMetric::findMetricByCodeStrict($dataSource->getAvailableMetrics(), 'total_revenue', false);\nif (!$metric) { /* skip or default */ }","handlingStrategy":"validation","validationCode":"$metrics = $dataSource->getAvailableMetrics();\n$known = array_map(fn(ReportMetric $m) => $m->getCode(), $metrics);\nif (!in_array($metricCode, $known, true)) {\n    // fix the code, or skip, or fail with a clear message\n    throw new InvalidArgumentException(\"Unknown metric '{$metricCode}'. Known: \" . implode(', ', $known));\n}\n$metric = ReportMetric::findMetricByCodeStrict($metrics, $metricCode);","typeGuard":"function metricExists(array $availableMetrics, string $code): bool\n{\n    foreach ($availableMetrics as $metric) {\n        if ($metric instanceof ReportMetric && $metric->getCode() === $code) {\n            return true;\n        }\n    }\n    return false;\n}","tryCatchPattern":"try {\n    $metric = ReportMetric::findMetricByCodeStrict($metrics, $metricCode);\n} catch (SystemException $e) {\n    // log and degrade instead of a 500 on stale dashboard configs\n    Log::warning($e->getMessage());\n    $metric = null;\n}","preventionTips":["Treat metric codes as stable public API: never rename them without migrating stored dashboard definitions.","Expose the list of valid metric codes to the front-end so UIs only offer selectable codes.","Use findMetricByCodeStrict(..., false) when absence is a normal, handleable case."],"tags":["dashboard","report-metric","lookup-failed","unknown-code"],"backgroundTag":"unknown-identifier-lookup","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}