apache/dubbo · error · IllegalArgumentException

value '%s' for key '%s' is not a long integer

Error message

value '%s' for key '%s' is not a long integer

What it means

Thrown by AbstractJsonUtilImpl.getNumberAsLong(Map,String) when obj contains key, the value is a String, but Long.parseLong throws NumberFormatException. This is the string-parse failure path for the long accessor; the IllegalArgumentException names the value and key. A true Double value is handled separately (error 194 for fractional, success for whole); non-Double/non-String values hit error 196.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/AbstractJsonUtilImpl.java:193

        assert obj != null;
        assert key != null;
        if (!obj.containsKey(key)) {
            return null;
        }
        Object value = obj.get(key);
        if (value instanceof Double) {
            Double d = (Double) value;
            long l = d.longValue();
            if (l != d) {
                throw new ClassCastException("Number expected to be long: " + d);
            }
            return l;
        }
        if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException(
                        String.format("value '%s' for key '%s' is not a long integer", value, key));
            }
        }
        throw new IllegalArgumentException(String.format("value '%s' for key '%s' is not a long integer", value, key));
    }

    /**
     * Gets a string from an object for the given key.  If the key is not present, this returns null.
     * If the value is not a String, throws an exception.
     */
    @Override
    public String getString(Map<String, ?> obj, String key) {
        assert obj != null;
        assert key != null;
        if (!obj.containsKey(key)) {
            return null;
        }
        Object value = obj.get(key);

View on GitHub (pinned to 3a3043227f)

Solutions

  1. If the value may be a decimal string, parse as Double then cast/round: (long) Double.parseDouble(s).
  2. Sanitize the string (trim, strip separators) before relying on it.
  3. If the field is genuinely fractional, use getNumberAsDouble instead.
  4. Align the producer to emit plain integer strings or JSON numbers.

Example fix

// before
Long ts = jsonUtil.getNumberAsLong(obj, "ts"); // "1700000000.0"
// after - tolerate decimal strings
Object raw = obj.get("ts");
Long ts = raw instanceof String ? (long) Double.parseDouble((String) raw) : jsonUtil.getNumberAsLong(obj, "ts");
Defensive patterns

Strategy: validation

Validate before calling

Object raw = obj.get(key);
if (raw instanceof String) {
    String s = (String) raw;
    try {
        Long.parseLong(s); // pre-check
    } catch (NumberFormatException e) {
        try { return (long) Double.parseDouble(s); }
        catch (NumberFormatException ignored) { return null; }
    }
}
return jsonUtil.getNumberAsLong(obj, key);

Type guard

private static boolean isParsableLong(Object value) {
    if (value instanceof Double) return value.equals(Math.rint((Double) value));
    if (value instanceof String) {
        try { Long.parseLong((String) value); return true; }
        catch (NumberFormatException e) { return false; }
    }
    return false;
}

Try / catch

try {
    return jsonUtil.getNumberAsLong(obj, key);
} catch (IllegalArgumentException e) {
    if (e.getMessage() != null && e.getMessage().contains("is not a long integer")) {
        Object raw = obj.get(key);
        if (raw instanceof String) return (long) Double.parseDouble((String) raw);
    }
    throw e;
}

Prevention

When it happens

Trigger: jsonUtil.getNumberAsLong(obj, key) where obj.get(key) is a String not parseable as a base-10 long — e.g. "1.5", "abc", "", "1_000", hex/scientific notation, or a decimal point where an integer was expected.

Common situations: A decimal string ("42.0") where a long ID was expected; thousands separators; locale formatting; a value within double range but written with a decimal portion; free-text where a number was expected.

Related errors


AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14). Data as JSON: /api/errors/db6e41cff7859759. Report an issue: GitHub.