SonarSource/sonarqube · error · NotFoundException

The following metric keys are not found: %s

Error message

The following metric keys are not found: %s

What it means

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.

Source

Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java:568

  }

  private List<ComponentDto> searchComponents(DbSession dbSession, ComponentTreeQuery componentTreeQuery) {
    Collection<String> qualifiers = componentTreeQuery.getQualifiers();
    if (qualifiers != null && qualifiers.isEmpty()) {
      return Collections.emptyList();
    }
    return dbClient.componentDao().selectDescendants(dbSession, componentTreeQuery);
  }

  private List<MetricDto> searchMetrics(DbSession dbSession, Set<String> metricKeys) {
    List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys);
    if (metrics.size() < metricKeys.stream().filter(key -> !key.equals("contains_ai_code")).count()) {
      List<String> foundMetricKeys = Lists.transform(metrics, MetricDto::getKey);
      Set<String> missingMetricKeys = Sets.difference(
        new LinkedHashSet<>(metricKeys),
        new LinkedHashSet<>(foundMetricKeys));

      throw new NotFoundException(format("The following metric keys are not found: %s", join(COMMA_JOIN_SEPARATOR,
        missingMetricKeys)));
    }
    String forbiddenMetrics = metrics.stream()
      .filter(UnsupportedMetrics.INSTANCE)
      .map(MetricDto::getKey)
      .sorted()
      .collect(Collectors.joining(COMMA_JOIN_SEPARATOR));
    checkArgument(forbiddenMetrics.isEmpty(), "Metrics %s can't be requested in this web service. Please use api/measures/component",
      forbiddenMetrics);
    return metrics;
  }

  private Table<String, MetricDto, ComponentTreeData.Measure> searchMeasuresByComponentUuidAndMetric(DbSession dbSession,
    ComponentDto baseComponent,
    ComponentTreeQuery componentTreeQuery, List<ComponentDto> components, List<MetricDto> metrics) {

    Map<String, MetricDto> metricsByKeys = Maps.uniqueIndex(metrics, MetricDto::getKey);
    MeasureTreeQuery measureQuery = MeasureTreeQuery.builder()

View on GitHub (pinned to 184c821202)

Solutions

  1. Remove or correct the missing keys named in the error message.
  2. Verify metric availability with api/metrics/search first.
  3. Do not treat 'contains_ai_code' as an error case — it is intentionally exempted from this check.
  4. Enable the plugin that supplies the missing custom metric, or drop it from the query.

Example fix

// before
metricKeys=ncloc,vulnerabilities,coverage_percent
// after
metricKeys=ncloc,vulnerabilities,coverage
Defensive patterns

Strategy: validation

Validate before calling

const known = new Set((await api.get('/api/metrics/search', {ps: 500})).metrics.map(m => m.key));
const missing = keys.filter(k => k !== 'contains_ai_code' && !known.has(k));
if (missing.length) throw new Error('Unknown metric keys: ' + missing.join(', '));

Try / catch

try { ... } catch (e) { if (e.response?.status === 404) { const missing = parseMissingKeys(e.message); return requestWithout(missing); } throw e; }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/0c8bf5b7cd4910e7. Report an issue: GitHub.