didi/DoKit · error · IndexOutOfBoundsException

Entry does not exist: " + index

Error message

Entry does not exist: " + index

What it means

When CollectionUtils.get receives an Iterator, it consumes elements decrementing index until it hits -1; if the iterator is exhausted first, the requested entry never existed and IndexOutOfBoundsException('Entry does not exist: <index>') is thrown. Note the message reports the already-decremented index, not the original one. The same guard protects callers that pass a Collection, since that path delegates to the Iterator branch.

Source

Thrown at Android/dokit-util/src/main/java/com/didichuxing/doraemonkit/util/CollectionUtils.java:730

        if (object instanceof Map) {
            Map map = (Map) object;
            Iterator iterator = map.entrySet().iterator();
            return get(iterator, index);
        } else if (object instanceof List) {
            return ((List) object).get(index);
        } else if (object instanceof Object[]) {
            return ((Object[]) object)[index];
        } else if (object instanceof Iterator) {
            Iterator it = (Iterator) object;
            while (it.hasNext()) {
                index--;
                if (index == -1) {
                    return it.next();
                } else {
                    it.next();
                }
            }
            throw new IndexOutOfBoundsException("Entry does not exist: " + index);
        } else if (object instanceof Collection) {
            Iterator iterator = ((Collection) object).iterator();
            return get(iterator, index);
        } else if (object instanceof Enumeration) {
            Enumeration it = (Enumeration) object;
            while (it.hasMoreElements()) {
                index--;
                if (index == -1) {
                    return it.nextElement();
                } else {
                    it.nextElement();
                }
            }
            throw new IndexOutOfBoundsException("Entry does not exist: " + index);
        } else {
            try {
                return Array.get(object, index);
            } catch (IllegalArgumentException ex) {

View on GitHub (pinned to 626827cddb)

Solutions

  1. For Collections and Maps, prefer size-checking first: index < CollectionUtils.size(object), or cast and use List.get.
  2. Request a fresh iterator() immediately before calling get; never share or reuse iterators.
  3. Treat this as an exhaustive-consumption operation: get(iterator, n) advances the iterator n+1 positions.

Example fix

// before
Iterator<Map.Entry<String,String>> it = map.entrySet().iterator();
// ... it consumed elsewhere ...
Object v = CollectionUtils.get(it, 0); // may throw: entry already consumed

// after
Object v = map.isEmpty() ? null : CollectionUtils.get(map, 0); // fresh iterator inside
Defensive patterns

Strategy: validation

Validate before calling

if (object instanceof Collection && index < ((Collection<?>) object).size()) {
    return CollectionUtils.get(object, index);
}
return null;

Try / catch

try { v = CollectionUtils.get(it, n); } catch (IndexOutOfBoundsException e) { v = null; }

Prevention

When it happens

Trigger: Calling get(iterator, n) where n >= remaining element count, including n == 0 on an already-exhausted or empty iterator; passing a Collection with index >= size (it forwards to the Iterator branch and throws the same message).

Common situations: Reusing a shared iterator that another consumer already advanced; TOCTOU between checking map.entrySet() size and calling get on its iterator while entries are removed; assuming an Iterator can be randomly accessed repeatedly.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/062634de2c71c20f. Report an issue: GitHub.