stanfordnlp/CoreNLP · error · NullPointerException

HeadFinder

Error message

HeadFinder 

What it means

Thrown by Tree.percolateHeadAnnotations when the supplied HeadFinder's determineHead() returns null for a tree node. Stanford NLP requires every non-leaf node to have a determinable head; a null result means the HeadFinder implementation cannot handle the node's label or structure. It signals a broken/mismatched HeadFinder rather than bad input data per se.

Solutions

  1. Use the correct language HeadFinder for the treebank (e.g. UniversalSemanticHeadFinder or CollinsHeadFinder for English PTB)
  2. Check your custom HeadFinder's determineHead() and add a rule (plus a default) covering every non-terminal label in your trees
  3. Inspect the tree printed in the message; remove or repair malformed nodes whose labels no head rule can match

Example fix

// before
tree.percolateHeadAnnotations(new ChineseHeadFinder()); // English trees -> null head
// after
tree.percolateHeadAnnotations(new UniversalSemanticHeadFinder());
Defensive patterns

Strategy: validation

Validate before calling

if (hf == null || tree == null) throw new IllegalArgumentException("need non-null HeadFinder and tree");

Type guard

boolean usableHeadFinder(HeadFinder hf) { return hf != null; }

Try / catch

try { tree.percolateHeadAnnotations(hf); } catch (NullPointerException e) { log.warn("HeadFinder returned null head: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling percolateHeadAnnotations(hf) (directly or via headTerminal/headPreTerminal/dependencies pipelines) with a HeadFinder whose determineHead() returns null — e.g. a custom HeadFinder with no rule matching the node's label, or a head finder applied to trees with labels it does not recognize (e.g. ChineseHeadFinder on English trees).

Common situations: Custom HeadFinder implementations with incomplete rules; using a language-specific head finder on trees from another treebank; trees with unusual/terminal-only structure passed to annotation passes during parsing or dependency conversion.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/trees/Tree.java:1178

    CoreLabel nodeLabel = (CoreLabel) label();

    if (isLeaf()) {
      return;
    }

    if (isPreTerminal()) {
      nodeLabel.set(TreeCoreAnnotations.HeadWordLabelAnnotation.class, (CoreLabel) children()[0].label());
      nodeLabel.set(TreeCoreAnnotations.HeadTagLabelAnnotation.class, nodeLabel);
      return;
    }

    for (Tree kid : children()) {
      kid.percolateHeadAnnotations(hf);
    }

    final Tree head = hf.determineHead(this);
    if (head == null) {
      throw new NullPointerException("HeadFinder " + hf + " returned null for " + this);
    } else if (head.isLeaf()) {
      nodeLabel.set(TreeCoreAnnotations.HeadWordLabelAnnotation.class, (CoreLabel) head.label());
      nodeLabel.set(TreeCoreAnnotations.HeadTagLabelAnnotation.class, (CoreLabel) head.parent(this).label());
    } else if (head.isPreTerminal()) {
      nodeLabel.set(TreeCoreAnnotations.HeadWordLabelAnnotation.class, (CoreLabel) head.children()[0].label());
      nodeLabel.set(TreeCoreAnnotations.HeadTagLabelAnnotation.class, (CoreLabel) head.label());
    } else {
      if (!(head.label() instanceof CoreLabel)) {
        throw new AssertionError("Horrible bug");
      }
      CoreLabel headLabel = (CoreLabel) head.label();
      nodeLabel.set(TreeCoreAnnotations.HeadWordLabelAnnotation.class, headLabel.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class));
      nodeLabel.set(TreeCoreAnnotations.HeadTagLabelAnnotation.class, headLabel.get(TreeCoreAnnotations.HeadTagLabelAnnotation.class));
    }
  }


  /**

View on GitHub (pinned to 1b7edd19c4)