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
- Supply arguments in complete key/value pairs — add the missing partner or remove the orphan.
- When building from a collection, assert even size before spreading.
- 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
- Supply arguments in complete key/value pairs.
- Use Map.of (Java 9+) for literal maps to avoid parity mistakes.
- Assert even size when spreading a dynamic list into toMap.
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
- pairs must be even.
- The map value must be unique.
- expectedSize cannot be negative but was: {expectedSize}
- Invalid configurator rule, please specify at least one param
- service field in configuration is null.
AI-assisted analysis of apache/dubbo@3a3043227f (2026-08-14).
Data as JSON: /api/errors/0c6bda2d283d26df.
Report an issue: GitHub.