oracle/graal · error · NoSuchElementException
Empty iterator does not have elements
Error message
Empty iterator does not have elements
What it means
The shared EMPTY_ITERATOR singleton (returned by getKeys() of an empty EconomicMap, iterator() of empty iterables, and EmptySet iteration) throws NoSuchElementException from next() because it yields no elements. hasNext() always returns false; calling next() without checking hasNext() is the classic iteration protocol violation.
Source
Thrown at sdk/src/org.graalvm.collections/src/org/graalvm/collections/EmptyMap.java:87
public Object getValue() {
throw new NoSuchElementException("Empty cursor does not have elements");
}
@Override
public Object setValue(Object newValue) {
throw new NoSuchElementException("Empty cursor does not have elements");
}
};
static final Iterator<Object> EMPTY_ITERATOR = new Iterator<>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
throw new NoSuchElementException("Empty iterator does not have elements");
}
};
static final Iterable<Object> EMPTY_ITERABLE = new Iterable<>() {
@Override
public Iterator<Object> iterator() {
return EMPTY_ITERATOR;
}
};
static final EconomicMap<Object, Object> EMPTY_MAP = new EconomicMap<>() {
@Override
public Object put(Object key, Object value) {
EconomicMapImpl.checkNonNull(key);
throw new IllegalArgumentException("Cannot modify the always-empty map");
}
@OverrideView on GitHub (pinned to a66e9ccd1d)
Solutions
- Always gate next() with hasNext(): while (it.hasNext()) { it.next(); } or use the enhanced-for statement.
- Check isEmpty() before obtaining/using the iterator when empties are expected.
- Prefer getEntries()/getKeys() with enhanced-for so the protocol cannot be violated.
Example fix
// before Iterator<K> it = map.getKeys().iterator(); K k = it.next(); // throws on empty map // after Iterator<K> it = map.getKeys().iterator(); K k = it.hasNext() ? it.next() : null;
Defensive patterns
Strategy: validation
Validate before calling
Iterator<K> it = map.getKeys().iterator(); K k = it.hasNext() ? it.next() : null;
Prevention
- Always pair next() with a preceding hasNext() check.
- Prefer enhanced-for loops over manual iterators.
- Use isEmpty() to skip empty collections before iterating.
When it happens
Trigger: Calling next() on the iterator returned by an empty EconomicMap.getKeys().iterator(), EmptySet-style iteration, or any Iterable backed by EmptyMap.EMPTY_ITERABLE, without a preceding true hasNext().
Common situations: Hand-written for-loops using a saved iterator after hasNext() returned false; enhanced-for loops are safe, but manual it.next() in while(true) style loops are not; streams/spliterator bridges that call next() eagerly.
Related errors
- Empty cursor does not have elements
- map grown too large!
- endless collision link cycle, most likely due to unsynchroni
- null not supported
- Cannot modify the always-empty map
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/7300163b2707789a.
Report an issue: GitHub.