SonarSource/sonarqube · error · IllegalArgumentException

Quality Gate: Unable to parse value

Error message

Quality Gate: Unable to parse value '%s' to compare against %s

What it means

ConditionEvaluator.evaluateCondition() compares a measure against a Quality Gate condition's error threshold. parseConditionValue() throws NumberFormatException when either the threshold or the measure is not a parseable number; the catch block rethrows it as IllegalArgumentException 'Quality Gate: Unable to parse value ...'. The message reports the error threshold and metric name that could not be compared numerically.

Solutions

  1. Edit the Quality Gate condition and set the error threshold to a plain decimal number (e.g. '85' not '85%', use '.' not ',')
  2. Check the metric: conditions only make sense on numeric metrics; move the condition to a numeric metric (e.g. coverage, duplicated_lines_density)
  3. If set via API, POST numeric thresholds without units or thousands separators

Example fix

// before: threshold with unit / comma decimal
"coverage": "85%"        // fails
"new_violations": "1,5"  // fails
// after
"coverage": "85"
"new_violations": "1.5"
Defensive patterns

Strategy: validation

Validate before calling

static boolean isNumericThreshold(String threshold) {
  if (threshold == null || threshold.isBlank()) return false;
  try { Double.parseDouble(threshold.trim()); return true; } catch (NumberFormatException e) { return false; }
}
// before creating a condition: if (!isNumericThreshold("85")) strip units/locale commas;

Type guard

static Optional<Double> asDouble(String s) {
  try { return Optional.of(Double.parseDouble(s.trim())); } catch (NumberFormatException | NullPointerException e) { return Optional.empty(); }
}

Try / catch

try {
  Optional<EvaluationResult> r = evaluator.evaluate(condition, measure);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Quality Gate: Unable to parse value")) {
    throw new ConfigurationException("Fix threshold: plain decimal, no % or comma: " + condition.getErrorThreshold());
  }
  throw e;
}

Prevention

When it happens

Trigger: A Quality Gate condition on a numeric metric (e.g. coverage, lines) has an error threshold that is not a plain number — like '85%', '1.5h', empty string, or a comma decimal '99,9' — while evaluating conditions in computeQualityGateSteps for a project's measures.

Common situations: Admins typing thresholds with units ('80%') or locale commas in the Quality Gate editor, conditions created via API/web service with malformed values, or string/duration metrics used with numeric comparison operators.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/qualitygate/ConditionEvaluator.java:65

    Comparable measureComparable = parseMeasure(measure);
    if (measureComparable == null) {
      return new EvaluationResult(Measure.Level.OK, null);
    }

    return evaluateCondition(condition, measureComparable)
      .orElseGet(() -> new EvaluationResult(Measure.Level.OK, measureComparable));
  }

  private static Optional<EvaluationResult> evaluateCondition(Condition condition, Comparable<?> measureComparable) {
    try {
      Comparable conditionComparable = parseConditionValue(condition.getMetric(), condition.getErrorThreshold());
      if (doesReachThresholds(measureComparable, conditionComparable, condition)) {
        return of(new EvaluationResult(Measure.Level.ERROR, measureComparable));
      }
      return Optional.empty();
    } catch (NumberFormatException badValueFormat) {
      throw new IllegalArgumentException(String.format(
        "Quality Gate: Unable to parse value '%s' to compare against %s",
        condition.getErrorThreshold(), condition.getMetric().getName()));
    }
  }

  private static boolean doesReachThresholds(Comparable measureValue, Comparable criteriaValue, Condition condition) {
    int comparison = measureValue.compareTo(criteriaValue);
    switch (condition.getOperator()) {
      case GREATER_THAN:
        return comparison > 0;
      case LESS_THAN:
        return comparison < 0;
      default:
        throw new IllegalArgumentException(String.format("Unsupported operator '%s'", condition.getOperator()));
    }
  }

  private static Comparable parseConditionValue(Metric metric, String value) {

View on GitHub (pinned to 184c821202)