SonarSource/sonarqube · error · IllegalArgumentException
Value '%s' is not a number
Error message
Value '%s' is not a number
What it means
Metric criteria in the project measures search must carry a numeric value. parseValue, called from createMetricCriterion, uses Double.parseDouble and rethrows NumberFormatException as this IllegalArgumentException when the criterion value is not parseable as a number.
Source
Thrown at server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactory.java:167
private static void processMetricCriterion(Criterion criterion, ProjectMeasuresQuery query) {
checkOperator(criterion);
checkValue(criterion);
query.addMetricCriterion(createMetricCriterion(criterion, criterion.getKey().toLowerCase(ENGLISH), criterion.getOperator()));
}
private static MetricCriterion createMetricCriterion(Criterion criterion, String metricKey, Operator operator) {
if (NO_DATA.equalsIgnoreCase(criterion.getValue())) {
checkArgument(EQ.equals(operator), "%s can only be used with equals operator", NO_DATA);
return MetricCriterion.createNoData(metricKey);
}
return MetricCriterion.create(metricKey, operator, parseValue(criterion.getValue()));
}
private static double parseValue(String value) {
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(format("Value '%s' is not a number", value));
}
}
private static void checkValue(Criterion criterion) {
checkArgument(criterion.getValue() != null, "Value cannot be null for '%s'", criterion.getKey());
}
private static void checkOperator(Criterion criterion) {
checkArgument(criterion.getOperator() != null, "Operator cannot be null for '%s'", criterion.getKey());
}
}
View on GitHub (pinned to 184c821202)
Solutions
- Ensure the metric value is a plain number using '.' as decimal separator (e.g. 'coverage >= 80').
- Strip units, currency symbols, thousands separators and whitespace from the value.
- Check that the criterion did not get split so the operator/value landed in the wrong field.
- Handle percentages as 0-100 numbers (e.g. coverage >= 80, not 0.8).
Example fix
// before String criteria = "ncloc > 1,000"; // comma not parseable // after String criteria = "ncloc > 1000";
Defensive patterns
Strategy: validation
Validate before calling
if (!value.matches("-?\\d+(\\.\\d+)?")) {
throw new IllegalArgumentException("Metric value must be a plain number with '.' decimal separator: " + value);
} Try / catch
try {
response = ws.searchProjects("coverage >= " + value);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("is not a number")) {
double normalized = Double.parseDouble(value.replace(',', '.'));
response = ws.searchProjects("coverage >= " + normalized);
} else throw e;
} Prevention
- Normalize values programmatically: strip units/separators, replace ',' with '.'.
- Format numbers with Locale.ROOT / toPlainString to avoid locale separators.
- Never embed user-displayed measure strings directly into criteria.
When it happens
Trigger: Sending a metric criterion with a non-numeric or empty value, e.g. 'coverage >= abc', 'ncloc > "1,000"' (comma thousand separator), 'coverage >= ' (empty), or locale-formatted numbers like '95,5'.
Common situations: Copy-pasting displayed measure values (with units or separators) into filters; localization producing comma decimal separators; forgetting to quote/escape values so the parser splits incorrectly.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Message '%s' cannot be dismissed.
- ${e.getMessage()}
- Cannot parse '%s' : %s
- Languages should be set either by using 'languages = java' o
- Tags should be set either by using 'tags = java' or 'tags IN
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/783eb28eb902d395.
Report an issue: GitHub.