alibaba/nacos · warning · IllegalArgumentException
expected one element but was: <{}>
Error message
expected one element but was: <{}> What it means
Thrown by CollectionUtils.getOnlyElement(Iterable) when the iterable is non-null and contains more than one element. The message is built by buildExceptionMessage and lists up to 5 of the offending elements followed by '...' if there are more. It enforces a single-element contract.
Source
Thrown at common/src/main/java/com/alibaba/nacos/common/utils/CollectionUtils.java:316
/**
* return the first element, if the iterator contains multiple elements, will throw {@code
* IllegalArgumentException}.
*
* @throws NoSuchElementException if the iterator is empty
* @throws IllegalArgumentException if the iterator contains multiple elements. The state of the iterator is
* unspecified.
*/
public static <T> T getOnlyElement(Iterable<T> iterable) {
if (iterable == null) {
throw new IllegalArgumentException("iterable cannot be null.");
}
Iterator<T> iterator = iterable.iterator();
T first = iterator.next();
if (!iterator.hasNext()) {
return first;
}
throw new IllegalArgumentException(buildExceptionMessage(iterator, first));
}
private static <T> String buildExceptionMessage(Iterator<T> iterator, T first) {
StringBuilder msg = new StringBuilder();
msg.append("expected one element but was: <");
msg.append(first);
for (int i = 0; i < 4 && iterator.hasNext(); i++) {
msg.append(", ");
msg.append(iterator.next());
}
if (iterator.hasNext()) {
msg.append(", ...");
}
msg.append('>');
return msg.toString();
}
/**View on GitHub (pinned to 9b989acdf1)
Solutions
- Tighten the upstream query/filter so it yields exactly one element.
- If multiple results are valid, use iterable.iterator().next() or pick by a deterministic tie-breaker instead of getOnlyElement.
- Log the element list from the exception message to see what duplicates exist.
Example fix
// before
T only = CollectionUtils.getOnlyElement(results);
// after
if (results.size() == 1) {
T only = results.iterator().next();
} else {
// handle ambiguity explicitly
throw new AmbiguousResultException(results);
} Defensive patterns
Strategy: validation
Validate before calling
if (iterable == null) return null;
int size = (iterable instanceof Collection) ? ((Collection<?>) iterable).size() : -1;
if (size == 1) {
return ((Collection<T>) iterable).iterator().next();
}
// size != 1 -> do not call getOnlyElement
return null; // or throw a domain-specific exception Try / catch
try {
return CollectionUtils.getOnlyElement(iterable);
} catch (IllegalArgumentException e) {
// more than one element — e.getMessage() lists them
throw new AmbiguousResultException(e.getMessage());
} Prevention
- Ensure the source query yields exactly one element before calling getOnlyElement.
- When duplicates are possible, use iterator().next() with explicit disambiguation.
When it happens
Trigger: Calling getOnlyElement on a collection that legitimately has 2+ elements when the caller assumed uniqueness — e.g., a query expected to match one record but matched several.
Common situations: A lookup/filter that should return exactly one result but the filter is too loose (duplicate config keys, multiple instances matching, ambiguous mapping).
Related errors
- Unsupported object type: null
- Unsupported object type: {}
- iterable cannot be null.
- Expected an array of elements (or empty array) but received
- 20002
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/868a0c98693974a4.
Report an issue: GitHub.