apache/dubbo · error · IllegalArgumentException
The map value must be unique.
Error message
The map value must be unique.
What it means
Thrown by CollectionUtils.flip when the source map has duplicate values. flip() reverses keys and values to produce Map<V,K>; if two keys share the same value, the reversal would silently lose an entry, so the method detects non-unique values (set size < map size) and refuses rather than corrupting data.
Source
Thrown at dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java:100
return list;
}
/**
* Flip the specified {@link Map}
*
* @param map The specified {@link Map},Its value must be unique
* @param <K> The key type of specified {@link Map}
* @param <V> The value type of specified {@link Map}
* @return {@link Map}
*/
@SuppressWarnings("unchecked")
public static <K, V> Map<V, K> flip(Map<K, V> map) {
if (isEmptyMap(map)) {
return (Map<V, K>) map;
}
Set<V> set = new HashSet<>(map.values());
if (set.size() != map.size()) {
throw new IllegalArgumentException("The map value must be unique.");
}
return map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
}
public static Map<String, Map<String, String>> splitAll(Map<String, List<String>> list, String separator) {
if (list == null) {
return null;
}
Map<String, Map<String, String>> result = new HashMap<>();
for (Map.Entry<String, List<String>> entry : list.entrySet()) {
result.put(entry.getKey(), split(entry.getValue(), separator));
}
return result;
}
public static Map<String, List<String>> joinAll(Map<String, Map<String, String>> map, String separator) {
if (map == null) {
return null;View on GitHub (pinned to 3a3043227f)
Solutions
- Deduplicate or disambiguate values before flipping (append a suffix, or keep Map<K, List<V>> via groupingBy).
- If collisions are expected, use a multi-valued flip: map.entrySet().stream().collect(groupingBy(Map.Entry::getValue, mapping(Map.Entry::getKey, toList()))).
- Verify the source data really should have unique values; fix the upstream producer if duplicates are a data bug.
Example fix
// before
Map<String,String> m = Map.of("a","x", "b","x");
CollectionUtils.flip(m); // throws: 'x' appears twice
// after (multi-valued)
Map<String,List<String>> flipped = m.entrySet().stream()
.collect(Collectors.groupingBy(Map.Entry::getValue,
Collectors.mapping(Map.Entry::getKey, Collectors.toList()))); Defensive patterns
Strategy: validation
Validate before calling
Map<String,String> map = /* ... */;
int distinct = new HashSet<>(map.values()).size();
if (distinct != map.size()) {
// duplicate values present; use a multi-valued flip instead
}
CollectionUtils.flip(map); Type guard
static <K,V> boolean hasUniqueValues(Map<K,V> map) {
return new HashSet<>(map.values()).size() == map.size();
} Prevention
- Check value uniqueness before flipping, or use groupingBy for a multi-valued reverse map.
- Disambiguate duplicate values upstream if a 1:1 flip is required.
- Document which side is authoritative when names map to multiple ids.
When it happens
Trigger: CollectionUtils.flip(map) where map.values() contains duplicates — i.e. two or more distinct keys map to equal values. The guard compares new HashSet<>(map.values()).size() to map.size().
Common situations: Inverting a lookup index (id->name) to (name->id) when names are not unique; flipping a config map where two config keys share a value; flipping a reverse-lookup that legitimately has collisions. The caller must decide which key wins or restructure the data.
Related errors
- pairs must be even.
- Map pairs can not be odd number.
- 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/dc0f2d5f63d5c20a.
Report an issue: GitHub.