stanfordnlp/CoreNLP · error · IllegalArgumentException
Can't return head of null or leaf Tree.
Error message
Can't return head of null or leaf Tree.
What it means
AbstractCollinsHeadFinder.determineHead computes the head child of a constituent using the nonTerminalInfo rule table. It refuses to operate on a null tree or a leaf (pre-terminal/word) node, because a head is only meaningful for a non-terminal with children. Throwing here signals a caller bug: head lookup was invoked on a node that can never have a head rule.
Solutions
- Check that the tree is non-null and non-leaf before calling determineHead: if (t != null && !t.isLeaf()) head = hf.determineHead(t, parent);
- Fix tree loading so leaves are always under pre-terminal (POS) nodes — trees from tokenized/leaf-attached sources must be re-bracketed.
- Verify the caller recursion only visits non-terminal children (t.children() of internal nodes).
Example fix
// before
Tree head = headFinder.determineHead(child, tree);
// after
if (child != null && !child.isLeaf()) {
Tree head = headFinder.determineHead(child, tree);
} Defensive patterns
Strategy: validation
Validate before calling
if (tree == null || tree.isLeaf()) { throw new IllegalArgumentException("determineHead requires a non-leaf tree"); } Type guard
boolean hasHead(Tree t) { return t != null && !t.isLeaf() && t.children().length > 0; } Try / catch
try { head = hf.determineHead(t, parent); } catch (IllegalArgumentException e) { head = null; /* leaf/null node: no head applies */ } Prevention
- Guard with t != null && !t.isLeaf() before any determineHead call
- Ensure parsed trees keep POS pre-terminals above leaves
- In recursive tree walkers, only call head finding on internal nodes
When it happens
Trigger: Calling determineHead(t) or determineHead(t, parent) with t == null, or with a leaf Tree (t.isLeaf() true, e.g. a word node from a Tree whose leaves were not wrapped in pre-terminals).
Common situations: Tree transformation code that walks all children including leaves and calls determineHead on each; parsing a tree where leaves were attached directly instead of under POS pre-terminals; passing a null tree from a failed read or an empty parse result.
Related errors
- attempt to get word when sentence and lattice are null!
- Bad number put into wordToNumber. Word is: \"" + input +…
- Bad number put into wordToNumber. Word is: \"" + curPart +…
- CANNOT EVEN CREATE ARRAYS OF ORIGINAL SIZE!!
- could not find matching word from lattice in parse…
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/dbf2e23aa8caafaf.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/AbstractCollinsHeadFinder.java:164
/**
* Determine which daughter of the current parse tree is the head.
*
* @param t The parse tree to examine the daughters of.
* If this is a leaf, {@code null} is returned
* @param parent The parent of t
* @return The daughter parse tree that is the head of {@code t}.
* Returns null for leaf nodes.
* @see Tree#percolateHeads(HeadFinder)
* for a routine to call this and spread heads throughout a tree
*/
@Override
public Tree determineHead(Tree t, Tree parent) {
if (nonTerminalInfo == null) {
throw new IllegalStateException("Classes derived from AbstractCollinsHeadFinder must create and fill HashMap nonTerminalInfo.");
}
if (t == null || t.isLeaf()) {
throw new IllegalArgumentException("Can't return head of null or leaf Tree.");
}
if (DEBUG) {
log.info("determineHead for " + t.value());
}
Tree[] kids = t.children();
Tree theHead;
// first check if subclass found explicitly marked head
if ((theHead = findMarkedHead(t)) != null) {
if (DEBUG) {
log.info("Find marked head method returned " +
theHead.label() + " as head of " + t.label());
}
return theHead;
}
// if the node is a unary, then that kid must be the headView on GitHub (pinned to 1b7edd19c4)