stanfordnlp/CoreNLP · error · ArrayIndexOutOfBoundsException
Out of bounds: >=
Error message
Out of bounds: %d >= %d
What it means
ConcurrentHashIndex.get(int i) throws ArrayIndexOutOfBoundsException when the requested index i is not smaller than the index's current size (indexSize). The index maps items to dense integer IDs; asking for an ID that was never assigned (or belongs to a stale snapshot) is out of bounds. The message reports the requested index and the current bound.
Solutions
- Check 0 <= i && i < index.size() before calling get(i)
- Treat indexOf() == Integer-UNKNOWN (-1) as 'item absent' and skip the get()
- Load the index from the same saved snapshot that produced the ids (saveToWriter/loadFromReader pair), not a rebuilt one
- Re-derive ids by calling indexOf(item) instead of caching ids across runs
Example fix
// before E item = index.get(savedId); // after int id = index.indexOf(item); E item2 = (id != -1) ? index.get(id) : null;
Defensive patterns
Strategy: validation
Validate before calling
if (id < 0 || id >= index.size()) {
throw new IllegalArgumentException("id " + id + " not present in index of size " + index.size());
}
E item = index.get(id); Type guard
// Java has no runtime type guard; use a bounds-check helper
static <E> E safeGet(ConcurrentHashIndex<E> idx, int i) {
return (i >= 0 && i < idx.size()) ? idx.get(i) : null;
} Try / catch
try {
E item = index.get(id);
} catch (ArrayIndexOutOfBoundsException e) {
log.warn("Stale/unknown id {} against index of size {}", id, index.size());
item = null; // fall back to re-indexing the item
} Prevention
- Never use indexOf()'s -1 (UNKNOWN_ID) as a get() argument
- Persist and restore the index itself (saveToWriter/loadFromReader) whenever you persist ids
- Re-derive ids with indexOf() instead of caching them across rebuilds
- Log index.size() alongside any id in diagnostics
When it happens
Trigger: Calling get(i) with an id returned by indexOf() as UNKNOWN (-1), an id saved to disk for a different index (deserialized via saveToWriter/loadFromReader into a new index), or an id >= size() of the live index.
Common situations: Persisting a model with index ids and loading it against a rebuilt/shorter index; using -1 (UNKNOWN_ID from indexOf) as a lookup key; concurrent modification where indexSize shrank or the caller held an old id.
Related errors
- Couldn't submit item to threadpool:
- Empty index
- Index outside the bounds
- Index not large enough to name all the array elements!
- Invalid phraseColIndex
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/6d0a6f6de696707b.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/util/concurrent/ConcurrentHashIndex.java:69
*/
public ConcurrentHashIndex(int initialCapacity) {
item2Index = new ConcurrentHashMap<>(initialCapacity);
indexSize = 0;
lock = new ReentrantLock();
Object[] arr = new Object[initialCapacity];
index2Item = new AtomicReference<>(arr);
}
@SuppressWarnings("unchecked")
@Override
public E get(int i) {
Object[] arr = index2Item.get();
if (i < indexSize) {
// arr.length guaranteed to be == to size() given the
// implementation of indexOf below.
return (E) arr[i];
}
throw new ArrayIndexOutOfBoundsException(String.format("Out of bounds: %d >= %d", i, indexSize));
}
@Override
public int indexOf(E o) {
Integer id = item2Index.get(o);
return id == null ? UNKNOWN_ID : id;
}
@Override
public int addToIndex(E o) {
Integer index = item2Index.get(o);
if (index != null) {
return index;
}
lock.lock();
try {
// Recheck stateView on GitHub (pinned to 1b7edd19c4)