stanfordnlp/CoreNLP · error · IllegalArgumentException
Expected tree labels to have their heads assigned. Failed…
Error message
Expected tree labels to have their heads assigned. Failed at: <tree>
What it means
After confirming the labels are CoreLabel, createTransitionSequenceHelper() reads TreeCoreAnnotations.HeadWordLabelAnnotation from the node and both children to decide the binary transition direction. If any head annotation is null, the tree's heads were never assigned, and it throws this IllegalArgumentException including the offending tree in the message.
Solutions
- Run head finding on the binarized tree before generating transitions (same preprocessing as ShiftReduceParser training).
- Use the library's training entry point rather than calling createTransitionSequence directly on raw treebank trees.
- Programmatically assign heads: apply a HeadFinder and set TreeCoreAnnotations.HeadWordLabelAnnotation on each node.
- Check the tree printed in the exception to find the node missing its head.
Example fix
// before List<Transition> trans = createTransitionSequence(tree, false, rootStates, null); // after TrainOptions opts = new TrainOptions(); List<Tree> prep = ShiftReduceParser.preprocessTrees(Collections.singletonList(tree), opts); List<Transition> trans = createTransitionSequence(prep.get(0), false, rootStates, null);
Defensive patterns
Strategy: validation
Validate before calling
CoreLabel lbl = (CoreLabel) tree.label();
if (lbl.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class) == null)
throw new IllegalArgumentException("Run head-finding before generating transitions: " + tree); Type guard
boolean hasHeadsAssigned(Tree t) {
if (!(t.label() instanceof CoreLabel)) return false;
if (((CoreLabel) t.label()).get(TreeCoreAnnotations.HeadWordLabelAnnotation.class) == null) return false;
for (Tree c : t.children()) if (!hasHeadsAssigned(c)) return false;
return true;
} Try / catch
try {
List<Transition> trans = CreateTransitionSequence.createTransitionSequence(tree, false, rootStates, null);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Expected tree labels to have their heads assigned")) {
// apply head finding to the offending tree, then retry
}
} Prevention
- Always run the trainer's head-finding preprocessing on binarized trees.
- Check for HeadWordLabelAnnotation before sequence generation.
- Use the exception's embedded tree to locate the node missing heads.
When it happens
Trigger: Generating transition sequences from trees that skipped the head-finding step (e.g. no SemanticGraphHeadFinder/HeadFinder pass) — heads are null for the node or either child.
Common situations: Training pipelines that load trees from a treebank file but forget the 'head-finding' preprocessing the shift-reduce trainer normally applies, or trees reconstructed programmatically without head annotations.
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
- ERROR: Relation extraction requires full syntactic analysis!
- Expected tree labels to be CoreLabel
- Unable to find words/tokens in
- unable to find sentences in
- CoreMap must have either a Calendar or DocDate annotation
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/d941727ee09ee1bb.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/parser/shiftreduce/CreateTransitionSequence.java:84
// This is the tricky part... need to decide if the binary
// transition is a left or right transition. This is done by
// looking at the existing heads of this node and its two
// children. The expectation is that the tree already has heads
// assigned; otherwise, exception is thrown
if (!(tree.label() instanceof CoreLabel) ||
!(tree.children()[0].label() instanceof CoreLabel) ||
!(tree.children()[1].label() instanceof CoreLabel)) {
throw new IllegalArgumentException("Expected tree labels to be CoreLabel");
}
CoreLabel label = (CoreLabel) tree.label();
CoreLabel leftLabel = (CoreLabel) tree.children()[0].label();
CoreLabel rightLabel = (CoreLabel) tree.children()[1].label();
CoreLabel head = label.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class);
CoreLabel leftHead = leftLabel.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class);
CoreLabel rightHead = rightLabel.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class);
if (head == null || leftHead == null || rightHead == null) {
throw new IllegalArgumentException("Expected tree labels to have their heads assigned. Failed at: " + tree);
}
boolean isRoot = rootOnlyStates.contains(tree.label().value());
if (head == leftHead) {
transitions.add(new BinaryTransition(tree.label().value(), BinaryTransition.Side.LEFT, isRoot));
} else if (head == rightHead) {
transitions.add(new BinaryTransition(tree.label().value(), BinaryTransition.Side.RIGHT, isRoot));
} else {
throw new IllegalArgumentException("Heads were incorrectly assigned: tree's head is not matched to either the right or left head");
}
} else {
throw new IllegalArgumentException("Expected a binarized tree");
}
}
}
View on GitHub (pinned to 1b7edd19c4)