stanfordnlp/CoreNLP · error · IllegalStateException

BinaryHeadFinder: unexpected tree:

Error message

BinaryHeadFinder: unexpected tree: 

What it means

BinaryHeadFinder.determineHead finds the head daughter of an already binarized tree: the only child, a child labeled with '@' (binarization marker), or the boundary child. If none applies and no fallback HeadFinder resolves it, it throws IllegalStateException naming the offending tree.

Solutions

  1. Construct BinaryHeadFinder with an appropriate fallback HeadFinder, e.g. new BinaryHeadFinder(new SemanticHeadFinder()) or the head finder matching your treebank
  2. Ensure trees are binarized (labels contain '@' on generated intermediate nodes) before head finding
  3. Use the treebank's normal HeadFinder instead of BinaryHeadFinder for unbinarized trees
  4. Log/print tree t from the exception message to see the unexpected structure and fix the upstream transformation

Example fix

// before
HeadFinder hf = new BinaryHeadFinder();
// after
HeadFinder hf = new BinaryHeadFinder(new SemanticHeadFinder());
Defensive patterns

Strategy: fallback

Validate before calling

// ensure trees are binarized before head finding
if (tree.depth() > 0 && tree.children().length > 2)
  throw new IllegalArgumentException("Tree not binarized: " + tree);

Type guard

boolean isBinarized(Tree t) {
  return t.isLeaf() || t.isPreTerminal() || t.numChildren() <= 2 ||
         t.firstChild().label().value().startsWith("@");
}

Try / catch

try { head = bhf.determineHead(t); } catch (IllegalStateException e) { head = semanticHF.determineHead(t); }

Prevention

When it happens

Trigger: Calling determineHead(t) on a binarized tree with 2+ children where neither the left child's label nor the right child's label starts with '@' and the rightmost child is not the BOUNDARY tag, with fallbackHF null or the fallback also returning null.

Common situations: Applying BinaryHeadFinder to non-binarized trees (e.g., raw Penn Treebank trees without '@' annotations), building the finder without a fallback head finder, custom tree transformations that strip '@' labels.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/e54ab6d0dc7a46d2. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/parser/lexparser/BinaryHeadFinder.java:37

  /**
   * Determine which daughter of the current parse tree is the head.
   * It assumes that the daughters already have had their heads
   * determined. Another method has to do the tree walking.
   *
   * @param t The parse tree to examine the daughters of
   * @return The parse tree that is the head.  The convention has been
   *         that this returns <code>null</code> if no head is found.
   *         But maybe it should throw an exception?
   */
  public Tree determineHead(Tree t) {
    Tree result = determineBinaryHead(t);
    if (result == null && fallbackHF != null) {
      result = fallbackHF.determineHead(t);
    }
    if (result != null) {
      return result;
    }
    throw new IllegalStateException("BinaryHeadFinder: unexpected tree: " + t);
  }
  
  public Tree determineHead(Tree t, Tree parent){
    Tree result = determineBinaryHead(t);
    if (result == null && fallbackHF != null) {
      result = fallbackHF.determineHead(t, parent);
    }
    if (result != null) {
      return result;
    }
    throw new IllegalStateException("BinaryHeadFinder: unexpected tree: " + t);
  }

  private Tree determineBinaryHead(Tree t) {
    if (t.numChildren() == 1) {
      return t.firstChild();
    } else {
      String lval = t.firstChild().label().value();

View on GitHub (pinned to 1b7edd19c4)