{"record":{"id":"fbca17975c77d885","repo":"stanfordnlp/CoreNLP","slug":"error-relation-extraction-requires-full-syntactic","errorCode":null,"errorMessage":"ERROR: Relation extraction requires full syntactic analysis!","messagePattern":"ERROR: Relation extraction requires full syntactic analysis!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ie/machinereading/BasicRelationFeatureFactory.java","lineNumber":142,"sourceCode":"  /**\n   * Creates all features for the datum corresponding to this relation mention\n   * Note: this assumes binary relations where both arguments are EntityMention\n   * @param features Stores all features\n   * @param rel The mention\n   * @param types Comma separated list of feature classes to use\n   */\n  public boolean addFeatures(Counter<String> features, RelationMention rel, List<String> types, Logger logger) {\n    // sanity checks: must have two arguments, and each must be an entity mention\n    if(rel.getArgs().size() != 2) return false;\n    if(! (rel.getArg(0) instanceof EntityMention)) return false;\n    if(! (rel.getArg(1) instanceof EntityMention)) return false;\n\n    EntityMention arg0 = (EntityMention) rel.getArg(0);\n    EntityMention arg1 = (EntityMention) rel.getArg(1);\n\n    Tree tree = rel.getSentence().get(TreeAnnotation.class);\n    if(tree == null){\n      throw new RuntimeException(\"ERROR: Relation extraction requires full syntactic analysis!\");\n    }\n    List<Tree> leaves = tree.getLeaves();\n    List<CoreLabel> tokens = rel.getSentence().get(TokensAnnotation.class);\n\n    // this assumes that both args are in the same sentence as the relation object\n    // let's check for this to be safe\n    CoreMap relSentence = rel.getSentence();\n    CoreMap arg0Sentence = arg0.getSentence();\n    CoreMap arg1Sentence = arg1.getSentence();\n    if(arg0Sentence != relSentence){\n      log.info(\"WARNING: Found relation with arg0 in a different sentence: \" + rel);\n      log.info(\"Relation sentence: \" + relSentence.get(TextAnnotation.class));\n      log.info(\"Arg0 sentence: \" + arg0Sentence.get(TextAnnotation.class));\n      return false;\n    }\n    if(arg1Sentence != relSentence){\n      log.info(\"WARNING: Found relation with arg1 in a different sentence: \" + rel);\n      log.info(\"Relation sentence: \" + relSentence.get(TextAnnotation.class));","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ie/machinereading/BasicRelationFeatureFactory.java#L124-L160","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nprops.setProperty(\"annotators\", \"tokenize,ssplit,pos,lemma,ner\");\n// after\nprops.setProperty(\"annotators\", \"tokenize,ssplit,pos,lemma,ner,parse\");","handlingStrategy":"type-guard","validationCode":"CoreMap sent = rel.getSentence();\nif (sent == null || sent.get(TreeAnnotation.class) == null) {\n  throw new IllegalStateException(\"Sentence lacks parse tree; add the 'parse' annotator before relation extraction.\");\n}","typeGuard":"boolean hasParse(RelationMention rel) {\n  CoreMap sent = rel.getSentence();\n  return sent != null && sent.get(TreeAnnotation.class) != null;\n}","tryCatchPattern":"try {\n  features = featureFactory.addFeatures(rel, ...);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"requires full syntactic analysis\")) {\n    log.severe(\"Pipeline missing parse annotator: \" + e.getMessage());\n    throw new IllegalArgumentException(\"Enable the 'parse' annotator in your StanfordCoreNLP pipeline\", e);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["java","nlp","missing-annotation"],"backgroundTag":"missing-required-config-field","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"}