apache/dubbo · error · IllegalArgumentException

Map pairs can not be odd number.

Error message

Map pairs can not be odd number.

What it means

Thrown by CollectionUtils.toMap when the varargs 'pairs' array has an odd length. Like toStringMap, toMap interprets arguments as alternating key,value pairs; an odd count means an unpaired key with no value, which cannot form a well-defined Map. Null/empty arrays return an empty map and do not throw.

Source

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

            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.");
        }
        int len = pairs.length / 2;
        for (int i = 0; i < len; i++) {
            ret.put((K) pairs[2 * i], (V) pairs[2 * i + 1]);
        }
        return ret;
    }

    @SuppressWarnings("unchecked")
    public static <K, V> Map<K, V> objToMap(Object object) throws IllegalAccessException {
        Map<K, V> ret = new HashMap<>();
        if (object != null) {
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(object);
                if (value != null) {
                    ret.put((K) field.getName(), (V) value);

View on GitHub (pinned to 3a3043227f)

Solutions

  1. Supply arguments in complete key/value pairs — add the missing partner or remove the orphan.
  2. When building from a collection, assert even size before spreading.
  3. Prefer Map.of(...) (Java 9+) for small literal maps to avoid parity mistakes entirely.

Example fix

// before
Map<Integer,String> m = CollectionUtils.toMap(1,"a",2); // throws

// after
Map<Integer,String> m = CollectionUtils.toMap(1,"a",2,"b");
// or Java 9+:
Map<Integer,String> m = Map.of(1,"a",2,"b");
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Prevention

When it happens

Trigger: CollectionUtils.toMap(pairs...) where pairs.length % 2 != 0 — e.g. toMap(1,"a",2) (3 args). The method casts elements unchecked to K and V, but the parity check runs first.

Common situations: Constructing a small map inline with an odd number of literals; a trailing element from a list spread with no partner; refactoring that drops one half of a pair. The unchecked casts (K/V) also mean type errors surface later as ClassCastException, but parity fails fast here.

Related errors


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