{"record":{"id":"cd11aa0c6b678c9f","repo":"SonarSource/sonarqube","slug":"there-is-no-metric-with-key-s","errorCode":null,"errorMessage":"There is no metric with key=%s","messagePattern":"There is no metric with key=(.+?)","errorType":"http","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java","lineNumber":132,"sourceCode":"    validateCondition(metric, operator, errorThreshold);\n    Collection<QualityGateConditionDto> otherConditions = getConditions(dbSession, condition.getQualityGateUuid())\n      .stream()\n      .filter(c -> !c.getUuid().equals(condition.getUuid()))\n      .toList();\n    checkConditionDoesNotExistOnEquivalentMetric(dbSession, otherConditions, metric);\n    condition\n      .setMetricUuid(metric.getUuid())\n      .setMetricKey(metric.getKey())\n      .setOperator(operator)\n      .setErrorThreshold(errorThreshold);\n    dbClient.gateConditionDao().update(condition, dbSession);\n    return condition;\n  }\n\n  private MetricDto getNonNullMetric(DbSession dbSession, String metricKey) {\n    MetricDto metric = dbClient.metricDao().selectByKey(dbSession, metricKey);\n    if (metric == null) {\n      throw new NotFoundException(format(\"There is no metric with key=%s\", metricKey));\n    }\n    return metric;\n  }\n\n  private Collection<QualityGateConditionDto> getConditions(DbSession dbSession, String qGateUuid) {\n    return dbClient.gateConditionDao().selectForQualityGate(dbSession, qGateUuid);\n  }\n\n  private void validateCondition(MetricDto metric, String operator, String errorThreshold) {\n    List<String> errors = new ArrayList<>();\n    validateMetric(metric, errors);\n    checkOperator(metric, operator, errors);\n    checkErrorThreshold(metric, errorThreshold, errors);\n    checkRatingMetric(metric, errorThreshold, errors);\n    checkRequest(errors.isEmpty(), errors);\n  }\n\n  private static void validateMetric(MetricDto metric, List<String> errors) {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java#L114-L150","documentation":"QualityGateConditionsUpdater.getNonNullMetric looks up a metric by key in the DB and throws NotFoundException when no metric matches, meaning the requested metric key does not exist on the server. This protects quality-gate conditions from referencing nonexistent metrics.","triggerScenarios":"POST api/qualitygates/create_condition or update_condition with a metricKey that is not in the metrics table (typo, custom metric deleted, metric from another SonarQube instance).","commonSituations":"Configuration-as-code copied between SonarQube servers where a custom metric only exists on one; metric keys renamed/removed in newer SonarQube versions; typos in metric keys like 'new_coverge' vs 'new_coverage'.","solutions":["List valid metrics with GET api/metrics/search and use an exact key from the response.","Create the missing custom metric (or restore it via configuration-as-code) before adding the condition.","Fix the typo in the metric key in your provisioning script.","Verify the target server actually defines the metric when migrating gate definitions between instances."],"exampleFix":"// before\ncreateCondition(gateId, \"new_coverge\", \"GT\", 80); // 404\n// after\nString key = searchMetrics(\"new_coverage\").stream()\n  .map(Metric::getKey)\n  .filter(k -> k.equals(\"new_coverage\"))\n  .findFirst()\n  .orElseThrow(() -> new IllegalStateException(\"metric not defined on server\"));\ncreateCondition(gateId, key, \"GT\", 80);","handlingStrategy":"validation","validationCode":"// before creating a condition, verify the metric key exists\nboolean exists = searchMetrics(metricKey) // GET api/metrics/search?q=<key>\n  .getMetrics().stream()\n  .anyMatch(m -> metricKey.equals(m.getKey()));\nif (!exists) throw new IllegalArgumentException(\"metric key not defined: \" + metricKey);","typeGuard":null,"tryCatchPattern":"try {\n  createCondition(gateId, metricKey, op, threshold);\n} catch (SonarQubeClientException e) {\n  if (e.getStatus() == 404 && String.valueOf(e.getMessage()).contains(\"no metric with key\")) {\n    throw new IllegalStateException(\"metric \" + metricKey + \" missing on this SonarQube server\", e);\n  }\n  throw e;\n}","preventionTips":["Copy metric keys only from GET api/metrics/search output","Diff metric definitions between servers when migrating quality-gate config","Keep custom metric provisioning in the same config-as-code pipeline as gate conditions"],"tags":["sonarqube","webapi","quality-gate","metrics","not-found"],"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"}