stanfordnlp/CoreNLP · error · IllegalArgumentException
Can only operate on preterminals
Error message
Can only operate on preterminals
What it means
replacePOSTag in FrenchTreeNormalizer rewrites the POS tag of a French tree node using MorphoFeatureSpecification, but it only accepts preterminal (POS-level) nodes whose labels are CoreLabel instances. The library throws IllegalArgumentException immediately when a node of any other shape is passed, because the downstream cast to CoreLabel and tag replacement would otherwise fail or corrupt the tree.
Solutions
- Traverse the tree and call normalizePreterminal only on preterminal nodes: check t.isPreTerminal() before invoking it
- Ensure the tree's labels are CoreLabel, e.g. build trees with CoreLabel factory or copy labels: label.setFromString(...) on a CoreLabel
- Run tree.transform(new FrenchTreeNormalizer(...)) / normalizeWholeTrees so the library itself iterates the correct node types
- Log or skip non-preterminal nodes instead of forcing them through the normalizer
Example fix
// before
normalizer.normalizePreterminal(sentenceTree, morpho); // throws: not a preterminal
// after
if (sentenceTree.isPreTerminal()) {
normalizer.normalizePreterminal(sentenceTree, morpho);
} else {
for (Tree pre : sentenceTree) {
if (pre.isPreTerminal()) normalizer.normalizePreterminal(pre, morpho);
}
} Defensive patterns
Strategy: validation
Validate before calling
// caller-side check
if (tree == null || !tree.isPreTerminal())
throw new IllegalArgumentException("normalizePreterminal requires a preterminal tree"); Type guard
static boolean isPreTerminalWithCoreLabel(Tree t) {
return t != null && t.isPreTerminal() && t.label() instanceof CoreLabel;
} Try / catch
try {
normalizer.normalizePreterminal(tree, morpho);
} catch (IllegalArgumentException e) {
log.warn("Skipping non-preterminal/non-CoreLabel node: " + e.getMessage());
} Prevention
- Only call normalizePreterminal inside a preterminal-filtered traversal (t.isPreTerminal())
- Use the library's normalizeWholeTrees/transform entry points instead of node-level calls
- Build French trees with CoreLabel-producing readers (FrenchTreeReaderFactory)
- Assert label types in your tree-loading unit tests
When it happens
Trigger: Calling replacePOSTag (directly or via normalizePreterminal) with a Tree whose !t.isPreTerminal() — e.g. a full sentence tree, an intermediate constituent like an NP/S, or a leaf word node — instead of a POS-tagged preterminal like (NN chat).
Common situations: Developers running the French morphological normalizer over a whole parsed tree without descending to preterminals first; using a custom TreeLabel or LabeledScoredTreeNode with String labels instead of CoreLabel; loading trees from a parser that doesn't use CoreLabel factories.
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
- %s: missing tag for %s
- %s: Splicing in DUMMYTAG for %s
- %s: Bare tagged word being wrapped in FRAG %s
- Unknown minimizer: {minimizer}
- Unknown clique: " + clique
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/32374779744c9d32.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/international/french/FrenchTreeNormalizer.java:70
}
};
}
@Override
public String normalizeTerminal(String terminal) {
if(terminal == null) return terminal;
return super.normalizeTerminal(terminal).intern();
}
@Override
public String normalizeNonterminal(String category) {
return super.normalizeNonterminal(category).intern();
}
private static void replacePOSTag(Tree t, MorphoFeatureSpecification morpho) {
if (!t.isPreTerminal()) {
throw new IllegalArgumentException("Can only operate on preterminals");
}
if (!(t.label() instanceof CoreLabel)) {
throw new IllegalArgumentException("Only operates on CoreLabels");
}
CoreLabel label = (CoreLabel) t.label();
Tree child = t.children()[0];
if (!(child.label() instanceof CoreLabel)) {
throw new IllegalArgumentException("Only operates on CoreLabels");
}
CoreLabel childLabel = (CoreLabel) child.label();
// Morphological Analysis
String morphStr = childLabel.originalText();
if (morphStr == null || morphStr.equals("")) {
morphStr = label.value();
// POS subcategoryView on GitHub (pinned to 1b7edd19c4)