{"record":{"id":"ce2ad9a6e9ed1883","repo":"stanfordnlp/CoreNLP","slug":"null-sentence-for-relation-rel","errorCode":null,"errorMessage":"NULL sentence for relation ${rel}","messagePattern":"NULL sentence for relation (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ie/machinereading/BasicRelationFeatureFactory.java","lineNumber":389,"sourceCode":"      for(int i = 0; i < rel.getArgs().size(); i ++){\n        Span s = ((EntityMention) rel.getArg(i)).getHead();\n        if(s.start() > 0){\n          String v = tokens.get(s.start() - 1).word();\n          features.setCount(\"leftarg\" + i + \"-\" + v, 1.0);\n        }\n        if(s.end() < tokens.size()){\n          String v = tokens.get(s.end()).word();\n          features.setCount(\"rightarg\" + i + \"-\" + v, 1.0);\n        }\n      }\n    }\n\n    // entities_between_args:  binary feature for each type specifying whether there is an entity of that type in the sentence\n    // between the two args.\n    // e.g. \"entity_between_args: Loc\" means there is at least one entity of type Loc between the two args\n    if (usingFeature(types, checklist, \"entities_between_args\")) {\n      CoreMap sent = rel.getSentence();\n      if(sent == null) throw new RuntimeException(\"NULL sentence for relation \" + rel);\n      List<EntityMention> relArgs = sent.get(MachineReadingAnnotations.EntityMentionsAnnotation.class);\n      if(relArgs != null) { // may be null due to annotation errors!\n        for (EntityMention arg : relArgs) {\n          if ((arg.getSyntacticHeadTokenPosition() > arg0.getSyntacticHeadTokenPosition() && arg.getSyntacticHeadTokenPosition() < arg1.getSyntacticHeadTokenPosition())\n                  || (arg.getSyntacticHeadTokenPosition() > arg1.getSyntacticHeadTokenPosition() && arg.getSyntacticHeadTokenPosition() < arg0.getSyntacticHeadTokenPosition())) {\n            features.setCount(\"entity_between_args: \" + arg.getType(), 1.0);\n          }\n        }\n      }\n    }\n\n    // entity_counts: For each type, the total number of entities of that type in the sentence (integer-valued feature)\n    // entity_counts_binary: Counts of entity types as binary features.\n    Counter<String> typeCounts = new ClassicCounter<>();\n    if(rel.getSentence().get(MachineReadingAnnotations.EntityMentionsAnnotation.class) != null){ // may be null due to annotation errors!\n      for (EntityMention arg : rel.getSentence().get(MachineReadingAnnotations.EntityMentionsAnnotation.class))\n        typeCounts.incrementCount(arg.getType());\n      for (String type : typeCounts.keySet()) {","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ie/machinereading/BasicRelationFeatureFactory.java#L371-L407","documentation":"In BasicRelationFeatureFactory.addFeatures, when the \"entities_between_args\" feature group is requested, the code fetches the relation's sentence CoreMap; if rel.getSentence() returns null it throws RuntimeException. This means the RelationMention was constructed without linking its containing sentence, so sentence-level features cannot be computed.","triggerScenarios":"Enabling the entities_between_args feature while processing a RelationMention whose sentence field was never set — typically a relation built manually or by a reader/extractor that does not attach the parent CoreMap sentence.","commonSituations":"Constructing RelationMentions programmatically for testing without calling setSentence; loading relations from a custom dataset loader that omits sentence linkage; entity/relation mentions split across pipelines so the relation object loses its provenance; annotation errors upstream (the code itself notes mentions may be null due to annotation errors).","solutions":["Ensure every RelationMention has its sentence set (setSentence / construct it with the parent CoreMap) before feature extraction.","Check for null before enabling sentence-dependent features: skip the feature group or drop the relation if getSentence() is null.","Fix the upstream annotation/reading code so mentions and relations are attached to their source sentence.","Validate the loaded corpus (assert rel.getSentence() != null) as a preprocessing step."],"exampleFix":"// before\nRelationMention rel = new RelationMention(...);\nrel.addArg(arg0); rel.addArg(arg1);\n// after\nRelationMention rel = new RelationMention(...);\nrel.setSentence(sentenceCoreMap);\nrel.addArg(arg0); rel.addArg(arg1);","handlingStrategy":"type-guard","validationCode":"if (rel.getSentence() == null) {\n  log.warning(\"Skipping relation \" + rel + \": no parent sentence attached\");\n  return;\n}","typeGuard":"boolean hasSentence(RelationMention rel) {\n  return rel != null && rel.getSentence() != null;\n}","tryCatchPattern":"try {\n  datum = featureFactory.createDatum(rel);\n} catch (RuntimeException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"NULL sentence\")) {\n    log.warning(\"Dropping relation without sentence: \" + rel);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Always construct mentions/relations with their parent sentence set.","Validate corpus loaders attach sentence provenance before feature extraction.","Treat sentence nullity as a data-quality signal and log it during preprocessing."],"tags":["java","nlp","null-reference"],"backgroundTag":"null-argument","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}