{"record":{"id":"3019884433137bca","repo":"stanfordnlp/CoreNLP","slug":"unexpected-class-while-looking-up","errorCode":null,"errorMessage":"Unexpected class  while looking up ","messagePattern":"Unexpected class  while looking up ","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java","lineNumber":831,"sourceCode":"            if (obj instanceof Phrase) {\n              // check rest of the phrase matches\n              Phrase phrase = (Phrase) obj;\n              if (acceptablePhrases == null || acceptablePhrases.contains(phrase)) {\n                int matchedTokenEnd = checkWordListMatch(\n                  phrase, tokens, cur.tokenStart, cur.tokenEnd, i+1, matchEnd);\n                if (matchedTokenEnd >= 0) {\n                  matched.add(new PhraseMatch(phrase, cur.tokenStart, matchedTokenEnd));\n                }\n              }\n            } else if (obj instanceof Map) {\n              todoStack.push(new StackEntry((Map<String,Object>) obj, cur.tokenStart, i+1, cur.tokenEnd, -1));\n            } else  {\n              throw new RuntimeException(\"Unexpected class in list \" + obj.getClass() + \" while looking up \" + word);\n            }\n          }\n          break;\n        } else {\n          throw new RuntimeException(\"Unexpected class \" + node.getClass() + \" while looking up \" + word);\n        }\n      }\n      if (cur.continueAt >= 0) {\n        int newStart = (cur.continueAt > cur.tokenStart)? cur.continueAt: cur.tokenStart+1;\n        if (newStart < cur.tokenEnd) {\n          todoStack.push(new StackEntry(cur.tree, newStart, newStart, cur.tokenEnd, newStart+1));\n        }\n      }\n    }\n    return matched;\n  }\n\n  public Iterator<Phrase> iterator() {\n    return new PhraseTableIterator(this);\n  }\n\n  private static class PhraseTableIterator extends AbstractIterator<Phrase> {\n    private PhraseTable phraseTable;","sourceCodeStart":813,"sourceCodeEnd":849,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java#L813-L849","documentation":"Companion to the list-element check: in the exhaustive lookup, the trie node retrieved for a word must itself be Map or List (with Phrase elements handled inline). Any other node class throws this RuntimeException, indicating internal trie corruption or an unexpected node type.","triggerScenarios":"Multi-match lookup where tree.get(word) yields a non-Map, non-List object - typically after external mutation of internal maps or concurrent addPhrase races.","commonSituations":"Reflection writes into the root tree; multi-threaded population; mixing PhraseTable instances or serialized structures across versions.","solutions":["Rebuild the PhraseTable cleanly using only public add APIs, single-threaded.","Treat the table as immutable after construction; share it across threads only after building completes.","Remove reflection/serialization code that touches internal node objects.","Report a reproducer to Stanford NLP if it occurs without external mutation."],"exampleFix":"// before\nroot.put(word, \"somestring\"); // invalid node\n// after\ntable.addPhrase(phraseText); // PhraseTable builds Map/List/Phrase nodes itself","handlingStrategy":"try-catch","validationCode":"// immutable-after-build discipline\nbuildTableOnce(phrases);","typeGuard":"boolean isLookupNode(Object o) { return o instanceof Map || o instanceof List; }","tryCatchPattern":"try { matches = table.lookupByRegex(...); } catch (RuntimeException e) { if (e.getMessage().contains(\"Unexpected class\")) { table = rebuildTable(phrases); } else { throw e; } }","preventionTips":["Only PhraseTable itself creates trie nodes.","Never add phrases during iteration/lookup.","Rebuild on corruption instead of patching internals."],"tags":["tokensregex","internal-state","type-mismatch"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}