{"record":{"id":"cfa1d7aaf8bff0d8","repo":"apache/dubbo","slug":"value-s-for-key-s-is-not-a-double","errorCode":null,"errorMessage":"value '%s' for key '%s' is not a double","messagePattern":"value '(.+?)' for key '(.+?)' is not a double","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJsonUtilImpl.java","lineNumber":129,"sourceCode":"     * Gets a number from an object for the given key.  If the key is not present, this returns null.\n     * If the value does not represent a double, throws an exception.\n     */\n    @Override\n    public Double getNumberAsDouble(Map<String, ?> obj, String key) {\n        assert obj != null;\n        assert key != null;\n        if (!obj.containsKey(key)) {\n            return null;\n        }\n        Object value = obj.get(key);\n        if (value instanceof Double) {\n            return (Double) value;\n        }\n        if (value instanceof String) {\n            try {\n                return Double.parseDouble((String) value);\n            } catch (NumberFormatException e) {\n                throw new IllegalArgumentException(\n                        String.format(\"value '%s' for key '%s' is not a double\", value, key));\n            }\n        }\n        throw new IllegalArgumentException(\n                String.format(\"value '%s' for key '%s' in '%s' is not a number\", value, key, obj));\n    }\n\n    /**\n     * Gets a number from an object for the given key, casted to an integer.  If the key is not\n     * present, this returns null.  If the value does not represent an integer, throws an exception.\n     */\n    @Override\n    public Integer getNumberAsInteger(Map<String, ?> obj, String key) {\n        assert obj != null;\n        assert key != null;\n        if (!obj.containsKey(key)) {\n            return null;\n        }","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJsonUtilImpl.java#L111-L147","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nDouble v = jsonUtil.getNumberAsDouble(obj, \"price\"); // \"12,99\"\n// after - normalize locale then read\nObject raw = obj.get(\"price\");\nDouble v = raw instanceof Number ? ((Number) raw).doubleValue()\n    : Double.parseDouble(((String) raw).replace(',', '.'));","handlingStrategy":"validation","validationCode":"Object raw = obj.get(key);\nif (raw instanceof String) {\n    String s = ((String) raw).trim().replace(',', '.');\n    try {\n        Double.parseDouble(s); // pre-check parseability\n    } catch (NumberFormatException ignored) {\n        // not a double; do not call getNumberAsDouble\n        return null;\n    }\n}\nreturn jsonUtil.getNumberAsDouble(obj, key);","typeGuard":"private static boolean isParsableDouble(Object value) {\n    if (value instanceof Double) return true;\n    if (value instanceof String) {\n        try { Double.parseDouble((String) value); return true; }\n        catch (NumberFormatException e) { return false; }\n    }\n    return false;\n}","tryCatchPattern":"try {\n    return jsonUtil.getNumberAsDouble(obj, key);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"is not a double\")) {\n        log.warn(\"non-double string at key={}: {}\", key, obj.get(key));\n        return null;\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["json","number-parsing","argument","jsonutil","dubbo-common"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}