{"record":{"id":"ce56a199e2d368a5","repo":"stanfordnlp/CoreNLP","slug":"unexpected-class-in-list-while-looking-up-word","errorCode":null,"errorMessage":"Unexpected class in list  while looking up word () in phrase ","messagePattern":"Unexpected class in list  while looking up word \\(\\) in phrase ","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java","lineNumber":571,"sourceCode":"        for (Object obj:lookupList) {\n          if (obj instanceof Phrase) {\n            // check rest of the phrase matches\n            Phrase phrase = (Phrase) obj;\n            int matchedTokenEnd = checkWordListMatch(\n              phrase, wordList, 0, wordList.size(), i, true);\n\n            if (matchedTokenEnd >= 0) {\n              return phrase;\n            }\n          } else if (obj instanceof Map) {\n            if (nMaps == 1) {\n              throw new RuntimeException(\"More than one map in list while looking up word \"\n                      + i + \"(\" + word + \") in phrase \" + wordList.toString());\n            }\n            tree = (Map<String, Object>) obj;\n            nMaps++;\n          } else  {\n            throw new RuntimeException(\"Unexpected class in list \" + obj.getClass() + \" while looking up word \"\n                    + i + \"(\" + word + \") in phrase \" + wordList.toString());\n          }\n        }\n        if (nMaps == 0) {\n          return null;\n        }\n      } else {\n        throw new RuntimeException(\"Unexpected class in list \" + node.getClass() + \" while looking up word \"\n                + i + \"(\" + word + \") in phrase \" + wordList.toString());\n      }\n    }\n    Phrase phrase = (Phrase) tree.get(PHRASE_END);\n    if (phrase != null) {\n      int matchedTokenEnd = checkWordListMatch(\n        phrase, wordList, 0, wordList.size(), wordList.size(), true);\n      return (matchedTokenEnd >= 0)? phrase:null;\n    } else {\n      return null;","sourceCodeStart":553,"sourceCodeEnd":589,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java#L553-L589","documentation":"While walking the trie during lookup, a List node must contain only Phrase and (at most one) Map elements. Encountering any other object type inside the list throws this RuntimeException, indicating the PhraseTable's internal structure was corrupted or tampered with.","triggerScenarios":"lookup(WordList) reaching a lookupList that holds an object that is neither Phrase nor Map - caused by concurrent addPhrase races or external mutation of the internal lists.","commonSituations":"Multi-threaded table construction; reflection/serialization experiments on the table; mixing objects from different PhraseTable instances.","solutions":["Rebuild the PhraseTable single-threaded (or under one lock) from the source phrase list.","Stop any code that touches the table's internal Map/List objects directly.","Use the immutable pattern: build once, then only call lookup/read methods from other threads.","Upgrade CoreNLP and report with a reproducer if corruption occurs without concurrent writes."],"exampleFix":"// before\nList<Object> list = (List<Object>) getRootTree().get(word);\nlist.add(myCustomObject); // poisons the table\n// after\ntable.addPhrases(Arrays.asList(myPhraseStrings)); // only public API","handlingStrategy":"validation","validationCode":"// only public API may touch the table; assert no reflective access\ntable.addPhrases(phrases); // then treat as immutable","typeGuard":"boolean isValidNode(Object o) { return o == null || o instanceof Phrase || o instanceof Map || o instanceof List; }","tryCatchPattern":"try { return table.lookup(wordList); } catch (RuntimeException e) { if (e.getMessage().contains(\"Unexpected class\")) { table = rebuild(phrases); return table.lookup(wordList); } throw e; }","preventionTips":["Use only addPhrase/addPhrases/lookup public methods.","Share the table across threads only after building completes.","Avoid serializing/deserializing internal structures across versions."],"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"}