apache/dubbo · error · IllegalArgumentException

pairs must be even.

Error message

pairs must be even.

What it means

Thrown by CollectionUtils.toStringMap when the varargs 'pairs' array has an odd length. The method treats arguments as key,value,key,value,... pairs; an odd count means the last key has no matching value, which would produce a malformed map, so it is rejected.

Source

Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java:216

    private static boolean objectEquals(Object obj1, Object obj2) {
        if (obj1 == null && obj2 == null) {
            return true;
        }
        if (obj1 == null || obj2 == null) {
            return false;
        }
        return obj1.equals(obj2);
    }

    public static Map<String, String> toStringMap(String... pairs) {
        Map<String, String> parameters = new HashMap<>();
        if (ArrayUtils.isEmpty(pairs)) {
            return parameters;
        }

        if (pairs.length > 0) {
            if (pairs.length % 2 != 0) {
                throw new IllegalArgumentException("pairs must be even.");
            }
            for (int i = 0; i < pairs.length; i = i + 2) {
                parameters.put(pairs[i], pairs[i + 1]);
            }
        }
        return parameters;
    }

    @SuppressWarnings("unchecked")
    public static <K, V> Map<K, V> toMap(Object... pairs) {
        Map<K, V> ret = new HashMap<>();
        if (pairs == null || pairs.length == 0) {
            return ret;
        }

        if (pairs.length % 2 != 0) {
            throw new IllegalArgumentException("Map pairs can not be odd number.");
        }

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Ensure the arguments come in complete key/value pairs — add the missing value or remove the dangling key.
  2. Build the map from a List or Map source first and check even size before spreading into toStringMap.
  3. Validate pairs.length % 2 == 0 before the call if the source is dynamic.

Example fix

// before
Map<String,String> m = CollectionUtils.toStringMap("k1","v1","k2"); // throws

// after
Map<String,String> m = CollectionUtils.toStringMap("k1","v1","k2","v2");
Defensive patterns

Strategy: validation

Validate before calling

String[] pairs = /* ... */;
if (pairs != null && pairs.length % 2 != 0) {
    throw new IllegalArgumentException("toStringMap needs even number of args (key,value,...)");
}
CollectionUtils.toStringMap(pairs);

Type guard

static boolean evenLength(String[] pairs) {
    return pairs == null || pairs.length % 2 == 0;
}

Prevention

When it happens

Trigger: CollectionUtils.toStringMap(pairs...) where pairs.length % 2 != 0 — e.g. toStringMap("k1","v1","k2") (3 args). Empty/null arrays are allowed (return empty map); only non-empty odd lengths throw.

Common situations: Programmatically building a parameter map from a list whose source had an odd number of elements; a trailing key with no value in a config builder; copy-paste dropping one element of a pair.

Related errors


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