stanfordnlp/CoreNLP · error · RuntimeException
Unmatched NE labels in MUC file
Error message
Unmatched NE labels in MUC file: {ner} v. {ner1} What it means
nextDoc parses MUC-format SGML documents token by token; when it closes a named-entity tag it compares the closing label with the currently open one and throws RuntimeException("Unmatched NE labels in MUC file: X v. Y") on mismatch. It means the MUC file's NE SGML tags are nested or malformed — an opening tag was left unclosed or closed with the wrong name.
Solutions
- Fix the MUC file so every NE open tag is closed by the matching close tag with proper nesting
- Re-generate the MUC file from a reliable source/converter
- Check for stray/typo'd close tags (e.g. </ORGANISATION> vs </ORGANIZATION>)
- Pre-validate SGML tag balance before feeding the file to the mention extractor
Example fix
// before <ORGANIZATION>Apple <PERSON>Tim Cook</ORGANIZATION></PERSON> <!-- bad nesting --> // after <ORGANIZATION>Apple</ORGANIZATION> <PERSON>Tim Cook</PERSON>
Defensive patterns
Strategy: validation
Validate before calling
// check NE tag balance before feeding a MUC file to MUCMentionExtractor
Deque<String> stack = new ArrayDeque<>();
Matcher m = Pattern.compile("</?([A-Z]+)>").matcher(mucFileText);
while (m.find()) {
if (m.group(0).startsWith("</")) {
if (stack.isEmpty() || !stack.pop().equals(m.group(1))) {
throw new IllegalStateException("Unmatched NE tag: " + m.group(0));
}
} else {
stack.push(m.group(1));
}
} Try / catch
try {
extractor.nextDoc();
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unmatched NE labels")) {
log.error("Malformed MUC SGML: " + e.getMessage());
}
throw e;
} Prevention
- Pre-validate SGML tag nesting in MUC files
- Use a standard converter to generate MUC format
- Watch for tag-name typos and case mismatches
- Test one document through the extractor before batch processing
When it happens
Trigger: MUCMentionExtractor.nextDoc reads a MUC file where </SOMETHING> appears while a different <SOMETHING> tag is still open (e.g. <ORGANIZATION> ... </PERSON>), or the tokenizer splits tags unexpectedly.
Common situations: Hand-edited or machine-generated MUC files with mismatched SGML tags, incorrectly nested NE markup, HTML-ish entities confusing the simple tokenizer, or files converted from another format with broken tags.
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.
Related errors
- Cannot find gold mention with ID=
- Shouldn't happen:
- Error reading saved links
- RuntimeIOException wrapping IOException
- Error creating data exporter
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/588c1dd6e1873e31.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/dcoref/MUCMentionExtractor.java:177
word.set(CoreAnnotations.NamedEntityTagAnnotation.class, "O");
}
}
sentence.add(word);
}
// found the start SGML tag for a NE, e.g., "<ORGANIZATION>"
else if (w.startsWith("<") && !w.startsWith("<COREF") && !w.startsWith("</")) {
Pattern nerPattern = Pattern.compile("<(.*?)>");
Matcher m = nerPattern.matcher(w);
m.find();
ner = m.group(1);
}
// found the end SGML tag for a NE, e.g., "</ORGANIZATION>"
else if (w.startsWith("</") && !w.startsWith("</COREF")) {
Pattern nerPattern = Pattern.compile("</(.*?)>");
Matcher m = nerPattern.matcher(w);
m.find();
String ner1 = m.group(1);
if (ner != null && !ner.equals(ner1)) throw new RuntimeException("Unmatched NE labels in MUC file: " + ner + " v. " + ner1);
ner = null;
}
// found the start SGML tag for a coref mention
else if (w.startsWith("<COREF")) {
Mention mention = new Mention();
// position of this mention in the sentence
mention.startIndex = sentence.size();
// extract GOLD info about this coref chain. needed for eval
Pattern idPattern = Pattern.compile("ID=\"(.*?)\"");
Pattern refPattern = Pattern.compile("REF=\"(.*?)\"");
Matcher m = idPattern.matcher(w);
m.find();
mention.mentionID = Integer.parseInt(m.group(1));
m = refPattern.matcher(w);
if (m.find()) {View on GitHub (pinned to 1b7edd19c4)