stanfordnlp/CoreNLP · error · IllegalArgumentException
Heads were incorrectly assigned: tree's head is not matched
Error message
Heads were incorrectly assigned: tree's head is not matched to either the right or left head
What it means
During training, CreateTransitionSequence converts a binarized constituency tree into a transition sequence. For each binarized compound node it checks whether the node's head word equals the left or right child's head; only then can it emit a LEFT or RIGHT BinaryTransition. This error means the tree's head-finding produced a head that matches neither child, indicating a corrupted or mis-headized tree.
Solutions
- Re-run head finding (tree.percolateHeads(headFinder)) after any tree transformation, before binarization
- Verify the trees passed to training are properly binarized and unmodified after head marking
- Check for custom HeadFinder or tree-editing code that changes leaf words so head word equality (==) breaks
- Regenerate training tree files from the original Treebank to discard corrupted annotations
Example fix
// before: editing trees then training directly
List<Tree> trees = readTrees();
trees.forEach(t -> pruneLeaves(t));
List<List<Transition>> seqs = CreateTransitionSequence.createTransitionSequences(trees, op);
// after: re-percolate heads before building sequences
trees.forEach(t -> { pruneLeaves(t); t.percolateHeads(new SemanticHeadFinder()); });
List<List<Transition>> seqs = CreateTransitionSequence.createTransitionSequences(trees, op); Defensive patterns
Strategy: validation
Validate before calling
Tree binarized = binarizer.transformTree(tree);
if (tree.headWord() == null || !isChildHead(tree, tree.headWord())) {
throw new IllegalStateException("Tree head does not match either child head; re-percolate heads");
} Try / catch
try {
seqs = CreateTransitionSequence.createTransitionSequences(trees, op);
} catch (IllegalArgumentException e) {
log.severe("Corrupt training tree: " + e.getMessage());
} Prevention
- Always percolate heads after every tree transformation
- Never edit leaf words after head-finding
- Sanity-check trees with a head-equality assertion before training
When it happens
Trigger: Calling createTransitionSequence (via createTransitionSequenceHelper) on a training tree whose internal node's head word is not identical (by reference) to either the left or right child's head word.
Common situations: Training data trees were modified after head-finding (e.g. relabeling or pruning leaves), a custom HeadFinder produced inconsistent heads, or trees were rebuilt/retagged without re-running head finding before binarization.
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
- BinaryHeadFinder: unexpected tree:
- This version of the parser does not support non-tree trainin
- can't have null topcat
- Expected a binarized tree
- Illegal beam size ${beamSize}
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/77d386e56fafedab.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/parser/shiftreduce/CreateTransitionSequence.java:92
!(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)