{"record":{"id":"77d386e56fafedab","repo":"stanfordnlp/CoreNLP","slug":"heads-were-incorrectly-assigned-tree-s-head-is-no","errorCode":null,"errorMessage":"Heads were incorrectly assigned: tree's head is not matched to either the right or left head","messagePattern":"Heads were incorrectly assigned: tree's head is not matched to either the right or left head","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/parser/shiftreduce/CreateTransitionSequence.java","lineNumber":92,"sourceCode":"          !(tree.children()[1].label() instanceof CoreLabel)) {\n        throw new IllegalArgumentException(\"Expected tree labels to be CoreLabel\");\n      }\n      CoreLabel label = (CoreLabel) tree.label();\n      CoreLabel leftLabel = (CoreLabel) tree.children()[0].label();\n      CoreLabel rightLabel = (CoreLabel) tree.children()[1].label();\n      CoreLabel head = label.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class);\n      CoreLabel leftHead = leftLabel.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class);\n      CoreLabel rightHead = rightLabel.get(TreeCoreAnnotations.HeadWordLabelAnnotation.class);\n      if (head == null || leftHead == null || rightHead == null) {\n        throw new IllegalArgumentException(\"Expected tree labels to have their heads assigned.  Failed at: \" + tree);\n      }\n      boolean isRoot = rootOnlyStates.contains(tree.label().value());\n      if (head == leftHead) {\n        transitions.add(new BinaryTransition(tree.label().value(), BinaryTransition.Side.LEFT, isRoot));\n      } else if (head == rightHead) {\n        transitions.add(new BinaryTransition(tree.label().value(), BinaryTransition.Side.RIGHT, isRoot));\n      } else {\n        throw new IllegalArgumentException(\"Heads were incorrectly assigned: tree's head is not matched to either the right or left head\");\n      }\n    } else {\n      throw new IllegalArgumentException(\"Expected a binarized tree\");\n    }\n  }\n}\n","sourceCodeStart":74,"sourceCodeEnd":99,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/parser/shiftreduce/CreateTransitionSequence.java#L74-L99","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: editing trees then training directly\nList<Tree> trees = readTrees();\ntrees.forEach(t -> pruneLeaves(t));\nList<List<Transition>> seqs = CreateTransitionSequence.createTransitionSequences(trees, op);\n\n// after: re-percolate heads before building sequences\ntrees.forEach(t -> { pruneLeaves(t); t.percolateHeads(new SemanticHeadFinder()); });\nList<List<Transition>> seqs = CreateTransitionSequence.createTransitionSequences(trees, op);","handlingStrategy":"validation","validationCode":"Tree binarized = binarizer.transformTree(tree);\nif (tree.headWord() == null || !isChildHead(tree, tree.headWord())) {\n  throw new IllegalStateException(\"Tree head does not match either child head; re-percolate heads\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  seqs = CreateTransitionSequence.createTransitionSequences(trees, op);\n} catch (IllegalArgumentException e) {\n  log.severe(\"Corrupt training tree: \" + e.getMessage());\n}","preventionTips":["Always percolate heads after every tree transformation","Never edit leaf words after head-finding","Sanity-check trees with a head-equality assertion before training"],"tags":["parser","training","head-finding","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}