{"record":{"id":"0c8bf5b7cd4910e7","repo":"SonarSource/sonarqube","slug":"the-following-metric-keys-are-not-found-s-0c8bf5","errorCode":null,"errorMessage":"The following metric keys are not found: %s","messagePattern":"The following metric keys are not found: (.+?)","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java","lineNumber":568,"sourceCode":"  }\n\n  private List<ComponentDto> searchComponents(DbSession dbSession, ComponentTreeQuery componentTreeQuery) {\n    Collection<String> qualifiers = componentTreeQuery.getQualifiers();\n    if (qualifiers != null && qualifiers.isEmpty()) {\n      return Collections.emptyList();\n    }\n    return dbClient.componentDao().selectDescendants(dbSession, componentTreeQuery);\n  }\n\n  private List<MetricDto> searchMetrics(DbSession dbSession, Set<String> metricKeys) {\n    List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys);\n    if (metrics.size() < metricKeys.stream().filter(key -> !key.equals(\"contains_ai_code\")).count()) {\n      List<String> foundMetricKeys = Lists.transform(metrics, MetricDto::getKey);\n      Set<String> missingMetricKeys = Sets.difference(\n        new LinkedHashSet<>(metricKeys),\n        new LinkedHashSet<>(foundMetricKeys));\n\n      throw new NotFoundException(format(\"The following metric keys are not found: %s\", join(COMMA_JOIN_SEPARATOR,\n        missingMetricKeys)));\n    }\n    String forbiddenMetrics = metrics.stream()\n      .filter(UnsupportedMetrics.INSTANCE)\n      .map(MetricDto::getKey)\n      .sorted()\n      .collect(Collectors.joining(COMMA_JOIN_SEPARATOR));\n    checkArgument(forbiddenMetrics.isEmpty(), \"Metrics %s can't be requested in this web service. Please use api/measures/component\",\n      forbiddenMetrics);\n    return metrics;\n  }\n\n  private Table<String, MetricDto, ComponentTreeData.Measure> searchMeasuresByComponentUuidAndMetric(DbSession dbSession,\n    ComponentDto baseComponent,\n    ComponentTreeQuery componentTreeQuery, List<ComponentDto> components, List<MetricDto> metrics) {\n\n    Map<String, MetricDto> metricsByKeys = Maps.uniqueIndex(metrics, MetricDto::getKey);\n    MeasureTreeQuery measureQuery = MeasureTreeQuery.builder()","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java#L550-L586","documentation":"ComponentTreeAction.searchMetrics performs the same missing-metric check as ComponentAction but with a carve-out: the 'contains_ai_code' key is filtered out of the comparison, and unsupported metrics are separately rejected downstream. It throws NotFoundException naming every requested metric key absent from the database.","triggerScenarios":"Calling api/measures/component_tree with a metricKeys list containing a key not present in the metrics table (excluding the special 'contains_ai_code' pseudo-key which is allowed to be missing).","commonSituations":"Querying component trees with hand-typed metric keys; scripts written for one SonarQube version using metrics removed in another; expecting plugin-provided metrics while the plugin is disabled.","solutions":["Remove or correct the missing keys named in the error message.","Verify metric availability with api/metrics/search first.","Do not treat 'contains_ai_code' as an error case — it is intentionally exempted from this check.","Enable the plugin that supplies the missing custom metric, or drop it from the query."],"exampleFix":"// before\nmetricKeys=ncloc,vulnerabilities,coverage_percent\n// after\nmetricKeys=ncloc,vulnerabilities,coverage","handlingStrategy":"validation","validationCode":"const known = new Set((await api.get('/api/metrics/search', {ps: 500})).metrics.map(m => m.key));\nconst missing = keys.filter(k => k !== 'contains_ai_code' && !known.has(k));\nif (missing.length) throw new Error('Unknown metric keys: ' + missing.join(', '));","typeGuard":null,"tryCatchPattern":"try { ... } catch (e) { if (e.response?.status === 404) { const missing = parseMissingKeys(e.message); return requestWithout(missing); } throw e; }","preventionTips":["Remember 'contains_ai_code' may be absent from the metrics table — exclude it from validation.","Validate all metricKeys against api/metrics/search before component_tree queries."],"tags":["webapi","metrics","not-found","sonarqube"],"backgroundTag":"resource-not-found","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}