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

  1. Rebuild the PhraseTable with addPhrases and never mutate its internals directly.
  2. Do not iterate while another thread is adding phrases; finish writes first.
  3. Use the public API (addPhrase, lookup) instead of touching internal structures.
  4. 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

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


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)