stanfordnlp/CoreNLP · error · IllegalArgumentException
Called headPreTerminal on a leaf:
Error message
Called headPreTerminal on a leaf:
What it means
headPreTerminal(HeadFinder) walks down from a node to its head preterminal (the head's parent of leaf). If called on a leaf node there is no preterminal below it, so the method throws IllegalArgumentException including the offending tree in the message.
Solutions
- Guard with isPreTerminal() or !isLeaf() before calling headPreTerminal
- Use a different accessor (e.g. headTerminal(hf) or the node itself) when starting from a leaf
- Fix HeadFinder rules if determineHead is returning leaves instead of preterminals
Example fix
// before
Tree p = node.headPreTerminal(hf);
// after
if (!node.isLeaf()) { Tree p = node.headPreTerminal(hf); } else { Tree p = node; } Defensive patterns
Strategy: type-guard
Validate before calling
if (node.isLeaf()) throw new IllegalStateException("headPreTerminal is undefined for leaves"); Type guard
Tree headPreTerminalSafe(Tree t, HeadFinder hf) { return t.isLeaf() ? t : (t.isPreTerminal() ? t : t.headPreTerminal(hf)); } Try / catch
try { return node.headPreTerminal(hf); } catch (IllegalArgumentException e) { log.warn("leaf passed to headPreTerminal"); return node; } Prevention
- Skip leaves when iterating nodes for head features
- Use headTerminal(hf) when a leaf result is acceptable
- Validate HeadFinder rules return preterminals, not leaves
When it happens
Trigger: Calling tree.headPreTerminal(headFinder) directly on a leaf Tree, or recursion reaching a leaf whose head path bottoms out at a leaf (e.g. determineHead returns a child that is itself a leaf).
Common situations: Feature-extraction loops that iterate all nodes including leaves and call headPreTerminal on each; head-finder rules misconfigured so heads resolve to leaves rather than preterminals.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Expected CoreLabel's to have after() text
- Expected CoreLabel's to have text
- Expected CoreLabels in the trees
- Expected leaves to be CoreLabels
- Sentence.toSentence: lengths differ
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/d107d1944012c148.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/Tree.java:1139
return headTerminal(hf, null);
}
/**
* Returns the preterminal tree that is the head of the tree.
* See {@link #isPreTerminal()} for
* the definition of a preterminal node. Beware that some tree nodes may
* have no preterminal head.
*
* @param hf The headfinding algorithm to use
* @return The head preterminal tree, if any, else {@code null}
* @throws IllegalArgumentException if called on a leaf node
*/
public Tree headPreTerminal(HeadFinder hf) {
if (isPreTerminal()) {
return this;
} else if (isLeaf()) {
throw new IllegalArgumentException("Called headPreTerminal on a leaf: " + this);
} else {
Tree head = hf.determineHead(this);
if (head != null) {
return head.headPreTerminal(hf);
}
log.info("Head preterminal is null: " + this);
return null;
}
}
/**
* Finds the head words of each tree and assigns
* HeadWordLabelAnnotation on each node pointing to the correct
* CoreLabel. This relies on the nodes being CoreLabels, so it
* throws an IllegalArgumentException if this is ever not true.
*/
public void percolateHeadAnnotations(HeadFinder hf) {
if (!(label() instanceof CoreLabel)) {View on GitHub (pinned to 1b7edd19c4)