{"record":{"id":"74319005508d2426","repo":"stanfordnlp/CoreNLP","slug":"unexpected-class-in-list-while-adding-word-in","errorCode":null,"errorMessage":"Unexpected class in list  while adding word () in phrase ","messagePattern":"Unexpected class in list  while adding word \\(\\) in phrase ","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java","lineNumber":418,"sourceCode":"          if (obj instanceof Phrase) {\n            // check rest of the phrase matches\n            Phrase oldphrase = (Phrase) obj;\n            int matchedTokenEnd = checkWordListMatch(\n              oldphrase, wordList, 0, wordList.size(), i, true);\n            if (matchedTokenEnd >= 0) {\n              oldPhraseNewFormAdded = oldphrase.addForm(phraseText);\n              phraseAdded = true;\n              break;\n            }\n          } else if (obj instanceof Map) {\n            if (nMaps == 1) {\n              throw new RuntimeException(\"More than one map in list while adding word \"\n                      + i + \"(\" + word + \") in phrase \" + phraseText);\n            }\n            tree = (Map<String, Object>) obj;\n            nMaps++;\n          } else  {\n            throw new RuntimeException(\"Unexpected class in list \" + obj.getClass() + \" while adding word \"\n                    + i + \"(\" + word + \") in phrase \" + phraseText);\n          }\n        }\n        if (!phraseAdded && nMaps == 0) {\n          // add to list\n          Phrase newphrase = new Phrase(wordList, phraseText, tag, phraseData);\n          lookupList.add(newphrase);\n          newPhraseAdded = true;\n          phraseAdded = true;\n          if (lookupList.size() > MAX_LIST_SIZE) {\n            // convert lookupList (should consist only of phrases) to map\n            Map newMap = new HashMap<String,Object>(lookupList.size());\n            for (Object obj:lookupList) {\n              if (obj instanceof Phrase) {\n                Phrase oldphrase = (Phrase) obj;\n                addPhrase(newMap, oldphrase, i+1);\n              } else  {\n                throw new RuntimeException(\"Unexpected class in list \" + obj.getClass() + \" while converting list to map\");","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java#L400-L436","documentation":"In the same list-node traversal, any element that is neither a Phrase nor a Map is rejected with 'Unexpected class in list ... while adding word'. The list node may only contain Phrase objects plus at most one continuation Map.","triggerScenarios":"A List trie node contains a foreign object type (String, Integer, custom object) inserted by external code, and addPhrase iterates past it while adding a word.","commonSituations":"Post-processing the internal tree (e.g. serializing/deserializing with generic types, or storing counts as raw objects inside the trie).","solutions":["Ensure only Phrase and Map instances ever enter list nodes; migrate any foreign payloads into the Phrase object's data field","Rebuild the table via the public API","Add an assertion when inserting into the tree to catch bad node types early"],"exampleFix":"// before\nlistNode.add(42); // stray count\n// after\nPhrase p = new Phrase(wordList, text, tag, 42); // store data in phraseData\nlistNode.add(p);","handlingStrategy":"try-catch","validationCode":"// validate only via library API; foreign objects must be stored in phraseData, not the tree\nif (listNodeHasForeignObjects) migrateToPhraseData();","typeGuard":"static boolean listElementsOk(List<?> l) { return l.stream().allMatch(o -> o instanceof Phrase || o instanceof Map); }","tryCatchPattern":"try { table.addPhrase(wordList, text, tag, data); } catch (RuntimeException e) { if (e.getMessage().startsWith(\"Unexpected class in list\")) { rebuildPhraseTableFromSource(); } else throw e; }","preventionTips":["Store metadata in Phrase's data field, not in tree nodes","Keep tree node types limited to Map/List/Phrase","Serialize/deserialize via PhraseTable APIs, not raw maps"],"tags":["tokensregex","internal-state","trie"],"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"}