stanfordnlp/CoreNLP · error · RuntimeException

NULL sentence for relation

Error message

NULL sentence for relation ${rel}

What it means

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.

Solutions

  1. Ensure every RelationMention has its sentence set (setSentence / construct it with the parent CoreMap) before feature extraction.
  2. Check for null before enabling sentence-dependent features: skip the feature group or drop the relation if getSentence() is null.
  3. Fix the upstream annotation/reading code so mentions and relations are attached to their source sentence.
  4. Validate the loaded corpus (assert rel.getSentence() != null) as a preprocessing step.

Example fix

// before
RelationMention rel = new RelationMention(...);
rel.addArg(arg0); rel.addArg(arg1);
// after
RelationMention rel = new RelationMention(...);
rel.setSentence(sentenceCoreMap);
rel.addArg(arg0); rel.addArg(arg1);
Defensive patterns

Strategy: type-guard

Validate before calling

if (rel.getSentence() == null) {
  log.warning("Skipping relation " + rel + ": no parent sentence attached");
  return;
}

Type guard

boolean hasSentence(RelationMention rel) {
  return rel != null && rel.getSentence() != null;
}

Try / catch

try {
  datum = featureFactory.createDatum(rel);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("NULL sentence")) {
    log.warning("Dropping relation without sentence: " + rel);
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/ce2ad9a6e9ed1883. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/ie/machinereading/BasicRelationFeatureFactory.java:389

      for(int i = 0; i < rel.getArgs().size(); i ++){
        Span s = ((EntityMention) rel.getArg(i)).getHead();
        if(s.start() > 0){
          String v = tokens.get(s.start() - 1).word();
          features.setCount("leftarg" + i + "-" + v, 1.0);
        }
        if(s.end() < tokens.size()){
          String v = tokens.get(s.end()).word();
          features.setCount("rightarg" + i + "-" + v, 1.0);
        }
      }
    }

    // entities_between_args:  binary feature for each type specifying whether there is an entity of that type in the sentence
    // between the two args.
    // e.g. "entity_between_args: Loc" means there is at least one entity of type Loc between the two args
    if (usingFeature(types, checklist, "entities_between_args")) {
      CoreMap sent = rel.getSentence();
      if(sent == null) throw new RuntimeException("NULL sentence for relation " + rel);
      List<EntityMention> relArgs = sent.get(MachineReadingAnnotations.EntityMentionsAnnotation.class);
      if(relArgs != null) { // may be null due to annotation errors!
        for (EntityMention arg : relArgs) {
          if ((arg.getSyntacticHeadTokenPosition() > arg0.getSyntacticHeadTokenPosition() && arg.getSyntacticHeadTokenPosition() < arg1.getSyntacticHeadTokenPosition())
                  || (arg.getSyntacticHeadTokenPosition() > arg1.getSyntacticHeadTokenPosition() && arg.getSyntacticHeadTokenPosition() < arg0.getSyntacticHeadTokenPosition())) {
            features.setCount("entity_between_args: " + arg.getType(), 1.0);
          }
        }
      }
    }

    // entity_counts: For each type, the total number of entities of that type in the sentence (integer-valued feature)
    // entity_counts_binary: Counts of entity types as binary features.
    Counter<String> typeCounts = new ClassicCounter<>();
    if(rel.getSentence().get(MachineReadingAnnotations.EntityMentionsAnnotation.class) != null){ // may be null due to annotation errors!
      for (EntityMention arg : rel.getSentence().get(MachineReadingAnnotations.EntityMentionsAnnotation.class))
        typeCounts.incrementCount(arg.getType());
      for (String type : typeCounts.keySet()) {

View on GitHub (pinned to 1b7edd19c4)