stanfordnlp/CoreNLP · error
: Word contains malformed morph annotation
Error message
%s: Word contains malformed morph annotation: %s
What it means
ArabicTreeNormalizer.normalizeWholeTree strips morphological analyses appended to leaf values with the MORPHO_MARK separator. If a leaf splits into other than exactly two parts, the tree value is malformed and the normalizer logs this error and leaves the leaf unchanged rather than crashing.
Solutions
- Inspect the offending leaf value printed in the message and remove duplicate/stray morph mark characters
- Ensure each annotated leaf has the form word + morphoMark + morphFeatures with no extra marks
- Re-export or re-clean the treebank file; re-run annotation from the raw source
- If intentional multi-part values are needed, pre-split them before normalization
Example fix
// before (leaf value) "word NAUF def nom" // after "word NAUF def nom" // exactly one MORPHO_MARK separating word and features
Defensive patterns
Strategy: validation
Validate before calling
String v = leaf.value();
if (v != null && v.contains(MorphoFeatureSpecification.MORPHO_MARK)) {
String[] toks = v.split(MorphoFeatureSpecification.MORPHO_MARK);
if (toks.length != 2) throw new IllegalArgumentException("bad morph annotation: " + v);
} Try / catch
try {
tree = normalizer.normalizeWholeTree(tree, treeFactory);
} catch (Exception e) {
log.warn("skipping malformed tree: " + e.getMessage());
} Prevention
- Keep exactly one MORPHO_MARK separator per annotated leaf
- Sanitize treebank files so the separator never appears inside words
- Never run morph annotation twice on the same tree
- Validate a sample of the treebank before full normalization
When it happens
Trigger: Normalizing an Arabic tree whose leaf value contains the morpho mark character but not exactly one occurrence separating word and morph features (e.g. 'word morphA morphB' or a stray mark with nothing after it).
Common situations: Preprocessed Arabic treebanks where the separator character appears inside the word itself; hand-edited trees; double-morph-annotation from running a pipeline twice.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Arabic does not support feature type: " + feat.toString()
- attempt to get word when sentence and lattice are null!
- Bad number put into wordToNumber. Word is: \"" + input +…
- Bad number put into wordToNumber. Word is: \"" + curPart +…
- Can't return head of null or leaf Tree.
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/cc705d4300084d76.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/trees/international/arabic/ArabicTreeNormalizer.java:133
normalizedString = super.normalizeNonterminal(category);
}
return normalizedString.intern();
}
@Override
public Tree normalizeWholeTree(Tree tree, TreeFactory tf) {
tree = tree.prune(emptyFilter, tf).spliceOut(aOverAFilter, tf);
for (Tree t : tree) {
if(t.isLeaf()) {
//Strip off morphological analyses and place them in the OriginalTextAnnotation, which is
//specified by HasContext.
if(t.value().contains(MorphoFeatureSpecification.MORPHO_MARK)) {
String[] toks = t.value().split(MorphoFeatureSpecification.MORPHO_MARK);
if (toks.length != 2) {
log.err(String.format("%s: Word contains malformed morph annotation: %s", this.getClass().getName(), t.value()));
} else if (t.label() instanceof CoreLabel) {
CoreLabel cl = (CoreLabel) t.label();
cl.setValue(toks[0].trim().intern());
cl.setWord(toks[0].trim().intern());
Pair<String,String> lemmaMorph = MorphoFeatureSpecification.splitMorphString(toks[0], toks[1]);
String lemma = lemmaMorph.first();
String morphAnalysis = lemmaMorph.second();
if (lemma.equals(toks[0])) {
cl.setOriginalText(toks[1].trim().intern());
} else {
// TODO(spenceg): Does this help?
String newLemma = lexMapper.map(null, lemma);
if (newLemma == null || newLemma.trim().isEmpty()) {
newLemma = lemma;
}
String newMorphAnalysis = newLemma + MorphoFeatureSpecification.LEMMA_MARK + morphAnalysis;
cl.setOriginalText(newMorphAnalysis.intern());View on GitHub (pinned to 1b7edd19c4)