apache/dubbo · error · IllegalArgumentException
value '%s' for key '%s' is not a double
Error message
value '%s' for key '%s' is not a double
What it means
Thrown by AbstractJsonUtilImpl.getNumberAsDouble(Map,String) when obj contains key, the value is a String, but Double.parseDouble rejects it (NumberFormatException). This is the string-parse failure path; the method first accepts a true Double, then attempts to parse a String. A value that is neither Double nor String hits a different message (error 190). The exception is an IllegalArgumentException naming the value and key.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJsonUtilImpl.java:129
* Gets a number from an object for the given key. If the key is not present, this returns null.
* If the value does not represent a double, throws an exception.
*/
@Override
public Double getNumberAsDouble(Map<String, ?> obj, String key) {
assert obj != null;
assert key != null;
if (!obj.containsKey(key)) {
return null;
}
Object value = obj.get(key);
if (value instanceof Double) {
return (Double) value;
}
if (value instanceof String) {
try {
return Double.parseDouble((String) value);
} catch (NumberFormatException e) {
throw new IllegalArgumentException(
String.format("value '%s' for key '%s' is not a double", value, key));
}
}
throw new IllegalArgumentException(
String.format("value '%s' for key '%s' in '%s' is not a number", value, key, obj));
}
/**
* Gets a number from an object for the given key, casted to an integer. If the key is not
* present, this returns null. If the value does not represent an integer, throws an exception.
*/
@Override
public Integer getNumberAsInteger(Map<String, ?> obj, String key) {
assert obj != null;
assert key != null;
if (!obj.containsKey(key)) {
return null;
}View on GitHub (pinned to 3a3043227f)
Solutions
- Sanitize the string before relying on it (trim, replace locale separators, strip units) or read it from a field guaranteed numeric.
- If the field is genuinely free-form, validate with a regex/Double-try before calling getNumberAsDouble and treat non-numeric as a domain error.
- Ensure the JSON producer emits numbers (not strings) for numeric fields.
- Catch IllegalArgumentException and fall back to a default or report the bad value.
Example fix
// before
Double v = jsonUtil.getNumberAsDouble(obj, "price"); // "12,99"
// after - normalize locale then read
Object raw = obj.get("price");
Double v = raw instanceof Number ? ((Number) raw).doubleValue()
: Double.parseDouble(((String) raw).replace(',', '.')); Defensive patterns
Strategy: validation
Validate before calling
Object raw = obj.get(key);
if (raw instanceof String) {
String s = ((String) raw).trim().replace(',', '.');
try {
Double.parseDouble(s); // pre-check parseability
} catch (NumberFormatException ignored) {
// not a double; do not call getNumberAsDouble
return null;
}
}
return jsonUtil.getNumberAsDouble(obj, key); Type guard
private static boolean isParsableDouble(Object value) {
if (value instanceof Double) return true;
if (value instanceof String) {
try { Double.parseDouble((String) value); return true; }
catch (NumberFormatException e) { return false; }
}
return false;
} Try / catch
try {
return jsonUtil.getNumberAsDouble(obj, key);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("is not a double")) {
log.warn("non-double string at key={}: {}", key, obj.get(key));
return null;
}
throw e;
} Prevention
- Normalize decimal separators (comma vs dot) and strip units before parsing.
- Pre-validate string numerics with Double.parseDouble in a try/catch before calling the accessor.
- Align the producer to emit JSON numbers, not strings, for numeric fields.
When it happens
Trigger: jsonUtil.getNumberAsDouble(obj, key) where obj.get(key) is a String that is not a valid double — e.g. "abc", "", "NaN-ish", "1,2,3" (comma instead of dot), localized number formats, or a value with surrounding text.
Common situations: Locale-specific decimal separators (comma vs dot); a free-text field misinterpreted as numeric; an empty string where a number was expected; a value like "12px" or "$10" that carries units/currency; whitespace-only strings.
Related errors
- value '%s' for key '%s' in '%s' is not a number
- value '%s' for key '%s' is not an integer
- value '%s' for key '%s' is not a long integer
- Number expected to be integer: ${d}
- Number expected to be long: ${d}
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/cfa1d7aaf8bff0d8.
Report an issue: GitHub.