stanfordnlp/CoreNLP · error · RuntimeException
ERROR: Relation extraction requires full syntactic analysis!
Error message
ERROR: Relation extraction requires full syntactic analysis!
What it means
BasicRelationFeatureFactory.addFeatures needs the parse tree of the relation's sentence (TreeAnnotation) to compute syntactic features such as constituent paths between arguments. If the input CoreMap sentence was never annotated with a parse, it throws RuntimeException. Relation extraction requires the full preprocessing pipeline (POS + parsing) to have run before feature extraction.
Solutions
- Add the "parse" (or "parser") annotator to your StanfordCoreNLP pipeline before relation extraction.
- Verify each sentence CoreMap has a non-null TreeAnnotation before invoking addFeatures.
- If using pre-annotated input, ensure the producer ran syntactic analysis and that serialization preserves the tree.
- Replace CoreAnnotations.TreeAnnotation checks with a guard that logs and skips unparseable sentences if degraded features are acceptable.
Example fix
// before
props.setProperty("annotators", "tokenize,ssplit,pos,lemma,ner");
// after
props.setProperty("annotators", "tokenize,ssplit,pos,lemma,ner,parse"); Defensive patterns
Strategy: type-guard
Validate before calling
CoreMap sent = rel.getSentence();
if (sent == null || sent.get(TreeAnnotation.class) == null) {
throw new IllegalStateException("Sentence lacks parse tree; add the 'parse' annotator before relation extraction.");
} Type guard
boolean hasParse(RelationMention rel) {
CoreMap sent = rel.getSentence();
return sent != null && sent.get(TreeAnnotation.class) != null;
} Try / catch
try {
features = featureFactory.addFeatures(rel, ...);
} catch (RuntimeException e) {
if (e.getMessage().contains("requires full syntactic analysis")) {
log.severe("Pipeline missing parse annotator: " + e.getMessage());
throw new IllegalArgumentException("Enable the 'parse' annotator in your StanfordCoreNLP pipeline", e);
}
throw e;
} Prevention
- Always include tokenize,ssplit,pos,parse (or a parser) in pipelines feeding relation extraction.
- Assert sentences have TreeAnnotation in a corpus preflight check.
- When sharing serialized annotations, include the parse tree or re-parse on load.
When it happens
Trigger: Calling createDatum/addFeatures on a Relation whose sentence CoreMap lacks TreeAnnotation — i.e. the text was not run through a parser annotator (or the parse was dropped) before relation extraction.
Common situations: Building an Annotation pipeline with only tokenize/ssplit/ner and skipping 'parse'; passing sentences extracted from a custom reader that does not attach TreeAnnotation; serializing/deserializing annotations and losing the Tree; running on pre-annotated data produced by an older pipeline version.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Expected tree labels to have their heads assigned. Failed…
- Unable to find words/tokens in
- unable to find sentences in
- CoreMap must have either a Calendar or DocDate annotation
- Unknown minimizer
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/fbca17975c77d885.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/ie/machinereading/BasicRelationFeatureFactory.java:142
/**
* Creates all features for the datum corresponding to this relation mention
* Note: this assumes binary relations where both arguments are EntityMention
* @param features Stores all features
* @param rel The mention
* @param types Comma separated list of feature classes to use
*/
public boolean addFeatures(Counter<String> features, RelationMention rel, List<String> types, Logger logger) {
// sanity checks: must have two arguments, and each must be an entity mention
if(rel.getArgs().size() != 2) return false;
if(! (rel.getArg(0) instanceof EntityMention)) return false;
if(! (rel.getArg(1) instanceof EntityMention)) return false;
EntityMention arg0 = (EntityMention) rel.getArg(0);
EntityMention arg1 = (EntityMention) rel.getArg(1);
Tree tree = rel.getSentence().get(TreeAnnotation.class);
if(tree == null){
throw new RuntimeException("ERROR: Relation extraction requires full syntactic analysis!");
}
List<Tree> leaves = tree.getLeaves();
List<CoreLabel> tokens = rel.getSentence().get(TokensAnnotation.class);
// this assumes that both args are in the same sentence as the relation object
// let's check for this to be safe
CoreMap relSentence = rel.getSentence();
CoreMap arg0Sentence = arg0.getSentence();
CoreMap arg1Sentence = arg1.getSentence();
if(arg0Sentence != relSentence){
log.info("WARNING: Found relation with arg0 in a different sentence: " + rel);
log.info("Relation sentence: " + relSentence.get(TextAnnotation.class));
log.info("Arg0 sentence: " + arg0Sentence.get(TextAnnotation.class));
return false;
}
if(arg1Sentence != relSentence){
log.info("WARNING: Found relation with arg1 in a different sentence: " + rel);
log.info("Relation sentence: " + relSentence.get(TextAnnotation.class));View on GitHub (pinned to 1b7edd19c4)