{"record":{"id":"58f4c6586ab6a5ea","repo":"stanfordnlp/CoreNLP","slug":"more-than-one-map-in-list-while-adding-word-in","errorCode":null,"errorMessage":"More than one map in list while adding word () in phrase ","messagePattern":"More than one map 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":412,"sourceCode":"        tree = (Map<String, Object>) node;\n      } else if (node instanceof List) {\n        // Search through list for matches to word (at this point, the table is small, so no Map)\n        List lookupList = (List) node;\n        int nMaps = 0;\n        for (Object obj:lookupList) {\n          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());","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ling/tokensregex/PhraseTable.java#L394-L430","documentation":"While descending a List trie node, addPhrase expects at most one nested Map (the continuation of the phrase prefix). Finding a second Map means the trie structure is invalid — two map children under the same list node — so it throws 'More than one map in list'.","triggerScenarios":"Adding phrases such that a list node accumulates a second Map element, e.g. inconsistent node layouts produced by prior bad insertions or by code mutating the tree directly.","commonSituations":"Custom/bulk insertion code that bypasses PhraseTable invariants; mixing phrase tables loaded from different formats into one tree with hand-written merge logic.","solutions":["Rebuild the phrase table from scratch using only public addPhrase calls","Find and remove the offending direct writes to the internal tree","Load all phrase sources through PhraseTable's own read/add methods so invariants hold"],"exampleFix":"// before\nlistNode.add(new HashMap<String,Object>()); // second map\n// after\ntable.addPhrase(...); // let the library create the single nested map","handlingStrategy":"fallback","validationCode":"// no pre-call check possible without touching internals; ensure all inserts go through addPhrase\nif (usedDirectTreeInsertion) rebuildTable();","typeGuard":"static boolean listNodeOk(List<?> l) { long maps = l.stream().filter(o -> o instanceof Map).count(); return maps <= 1 && 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(\"More than one map in list\")) { rebuildPhraseTableFromSource(); } else throw e; }","preventionTips":["Route all phrase insertion through public addPhrase","Avoid hand-merged tries from multiple sources","Rebuild the table from raw data when invariants break"],"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"}