{"record":{"id":"cd20226292cd049c","repo":"stanfordnlp/CoreNLP","slug":"tree-treenum-is-not-properly-binary","errorCode":null,"errorMessage":"Tree <treeNum> is not properly binary","messagePattern":"Tree <treeNum> is not properly binary","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/trees/OutputSubtrees.java","lineNumber":92,"sourceCode":"    } else {\n      remap = Collections.emptyMap();\n    }\n\n    MemoryTreebank treebank = new MemoryTreebank(\"utf-8\");\n    treebank.loadPath(INPUT, null);\n\n    final Writer output;\n    if (OUTPUT == null) {\n      output = IOUtils.encodedOutputStreamWriter(System.out, \"utf-8\");\n    } else {\n      output = IOUtils.getPrintWriter(OUTPUT, \"utf-8\");\n    }\n\n    int treeNum = 0;\n    for (Tree tree : treebank) {\n      ++treeNum;\n      if (ASSERT_BINARY && !tree.isBinary()) {\n        throw new RuntimeException(\"Tree \" + treeNum + \" is not properly binary\");\n      }\n      //System.out.println(tree);\n      //System.out.println(\"--------------\");\n      Iterable<Tree> subtrees = (ROOT_ONLY) ? Collections.singletonList(tree) : tree;\n      for (Tree subtree : subtrees) {\n        if (subtree.isLeaf()) {\n          continue;\n        }\n        String value = subtree.label().value();\n        List<Tree> leaves = Trees.leaves(subtree);\n        List<Label> labels = leaves.stream().map(x -> x.label()).collect(Collectors.toList());\n        String text = SentenceUtils.listToString(labels);\n        if (ignored.contains(value)) {\n          continue;\n        }\n        if (remap.containsKey(value)) {\n          value = remap.get(value);\n        }","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/trees/OutputSubtrees.java#L74-L110","documentation":"OutputSubtrees extracts subtrees from a treebank and, when ASSERT_BINARY is enabled (set via -assertBinary), requires every input tree to be strictly binary (each internal node has exactly two children). This guard throws a RuntimeException identifying the 1-based tree number of the first non-binary tree.","triggerScenarios":"Running OutputSubtrees.main with -assertBinary=true on a treebank containing flat/n-ary constituents (e.g. raw Penn Treebank trees with 3+ children under a node, or unary chains mishandled), typically when the trees were not passed through TreeBinarizer first.","commonSituations":"Feeding the original Penn Treebank (unbinarized) trees directly; using the wrong binarization options for the downstream model; concatenating treebanks where some files were binarized and others not.","solutions":["Binarize the trees before processing, e.g. with TreeBinarizer (boundaryGenerator) or by running the trees through a parser that binarizes.","Remove the -assertBinary flag if strict binary structure is not actually required, letting n-ary subtrees pass through.","Locate the offending tree (message gives the 1-based number) and inspect/repair its structure.","Ensure consistent preprocessing across all treebank files in the input path."],"exampleFix":"// before\nfor (Tree t : treebank) { outputSubtrees(t); }\n// after\nTreeBinarizer bin = TreeBinarizer.boundaryFactories? -> use:\nTreeBinarizer bin = TreeBinarizer.buildSimpleBinarizer(\"HEAD\", \"-TMP\", false, false, false, op, false, 1.0, 0, tlpp.getBasicCategoryFunction(), false);\nfor (Tree t : treebank) { outputSubtrees(bin.transformTree(t)); }","handlingStrategy":"validation","validationCode":"// Verify binary-ness before running OutputSubtrees\ntreebank.forEach(t -> {\n  for (Tree n : t) {\n    if (!n.isLeaf() && n.numChildren() != 2)\n      throw new IllegalArgumentException(\"Non-binary node found: \" + n.value());\n  }\n});","typeGuard":null,"tryCatchPattern":"try {\n  OutputSubtrees.main(args);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().endsWith(\"is not properly binary\")) {\n    log.error(e.getMessage() + \" — binarize input with TreeBinarizer first\");\n  } else throw e;\n}","preventionTips":["Always run trees through TreeBinarizer (or a parser's binarization) before binary-structure tools.","Apply the same preprocessing to every treebank file in a mixed corpus.","Omit -assertBinary when you intend to process unbinarized trees."],"tags":["trees","binarization","treebank","assertion"],"backgroundTag":"invalid-argument-value","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}