stanfordnlp/CoreNLP · error · java.lang.RuntimeException
Unexpected class in phrase table
Error message
Unexpected class in phrase table
What it means
The PhraseTable iterator walks the trie, pushing iterators for Map and List nodes and returning Phrase leaves. When it encounters a value that is neither Phrase, Map, nor List, it throws this RuntimeException - the table's structure is corrupted or contains an unsupported node type.
Solutions
- Rebuild the PhraseTable with addPhrases and never mutate its internals directly.
- Do not iterate while another thread is adding phrases; finish writes first.
- Use the public API (addPhrase, lookup) instead of touching internal structures.
- Report to Stanford NLP with the reported class name if the table was built normally.
Example fix
// before
for (Object o : table) { ... } // while another thread calls addPhrase
// after
// finish all addPhrase calls, then
for (Object o : table) { ... } Defensive patterns
Strategy: try-catch
Validate before calling
// no concurrent writes while iterating assert !isBuilding.get() : "cannot iterate while phrases are being added";
Type guard
boolean isIterableNode(Object o) { return o instanceof Phrase || o instanceof Map || o instanceof List; } Try / catch
try { for (Object p : table) { ... } } catch (RuntimeException e) { if (e.getMessage().contains("Unexpected class in phrase table")) { table = rebuildTable(phrases); } else { throw e; } } Prevention
- Finish all writes before iterating.
- Use table.iterator()/getPhrases() rather than internal structures.
- Rebuild the table if any corruption is detected.
When it happens
Trigger: Calling iterator() (e.g. via iterating the table or collecting phrases) on a table whose internal maps contain a foreign object type.
Common situations: External mutation of the root tree via reflection; concurrent addPhrase during iteration; deserialized tables from a different version.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Invalid nextBranchIndex=
- More than one map in list while adding word () in phrase
- More than one map in list while looking up word () in…
- Unexpected class in list while adding word () in phrase
- Unexpected class in list while converting list to map
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/1729fa34f545f1a2.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java:871
public PhraseTableIterator(PhraseTable phraseTable) {
this.phraseTable = phraseTable;
this.iteratorStack.push(this.phraseTable.rootTree.values().iterator());
this.next = getNext();
}
private Phrase getNext() {
while (!iteratorStack.isEmpty()) {
Iterator<Object> iter = iteratorStack.peek();
if (iter.hasNext()) {
Object obj = iter.next();
if (obj instanceof Phrase) {
return (Phrase) obj;
} else if (obj instanceof Map) {
iteratorStack.push(((Map) obj).values().iterator());
} else if (obj instanceof List) {
iteratorStack.push(((List) obj).iterator());
} else {
throw new RuntimeException("Unexpected class in phrase table " + obj.getClass());
}
} else {
iteratorStack.pop();
}
}
return null;
}
@Override
public boolean hasNext() {
return next != null;
}
@Override
public Phrase next() {
Phrase res = next;
next = getNext();
return res;View on GitHub (pinned to 1b7edd19c4)