stanfordnlp/CoreNLP · error · RuntimeException

RuntimeException wrapping IOException

Error message

RuntimeException wrapping IOException

What it means

In CoNLLMentionExtractor.nextDoc, the recallErrors debugging call performs IO (writing gold-vs-predicted mention comparison output). Any IOException it throws is wrapped in a plain RuntimeException so nextDoc's signature stays unchecked. The real problem is the IO performed by recallErrors, not coreference processing itself.

Solutions

  1. Check the exception's cause (getCause()) for the actual IOException and fix that IO target (create the directory, fix permissions).
  2. Verify the path configured for recall-error logging is writable, or disable recall error logging if not needed.
  3. Ensure sufficient disk space in the output location.
  4. Run in a working directory with write permissions, or redirect debug output to a writable location.
  5. If recallErrors output isn't wanted, avoid enabling that option so no IO occurs in nextDoc.

Example fix

// before
// recallErrors output path points to /nonexistent/dir/err.txt

// after
new File("/logs/dcoref").mkdirs(); // ensure directory exists before running
props.setProperty("coref.debug.logANEList", "false"); // or disable debug output
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure recallErrors output location is writable before running
File outDir = new File(recallErrorsOutputDir);
if (!outDir.exists() && !outDir.mkdirs())
  throw new IllegalStateException("Cannot create recall-errors dir");
if (!outDir.canWrite()) throw new IllegalStateException("Not writable: " + outDir);

Try / catch

try {
  Document doc = mentionExtractor.nextDoc();
} catch (RuntimeException e) {
  if (e.getCause() instanceof IOException) {
    logger.severe("recallErrors IO failed: " + e.getCause());
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling nextDoc with the recallErrors logging enabled (dcoref recall errors output configured) while the target output file/stream cannot be written — bad path, unwritable directory, or already-closed stream.

Common situations: Setting the recall error output path to a non-existent directory; running with read-only working directories or restricted container filesystems; disk full while dumping error comparisons.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/dcoref/CoNLLMentionExtractor.java:172

    // Initialize gold mentions
    List<List<Mention>> allGoldMentions = extractGoldMentions(conllDoc);

    List<List<Mention>> allPredictedMentions;
    if (Constants.USE_GOLD_MENTIONS) {
      //allPredictedMentions = allGoldMentions;
      // Make copy of gold mentions since mentions may be later merged, mentionID's changed and stuff
      allPredictedMentions = makeCopy(allGoldMentions);
    } else if (Constants.USE_GOLD_MENTION_BOUNDARIES) {
      allPredictedMentions = ((RuleBasedCorefMentionFinder) mentionFinder).filterPredictedMentions(allGoldMentions, anno, dictionaries);
    } else {
      allPredictedMentions = mentionFinder.extractPredictedMentions(anno, maxID, dictionaries);
    }

    try {
      recallErrors(allGoldMentions,allPredictedMentions,anno);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    Document doc = arrange(anno, allWords, allTrees, allPredictedMentions, allGoldMentions, true);
    doc.conllDoc = conllDoc;
    return doc;
  }

  private static List<List<Mention>> makeCopy(List<List<Mention>> mentions) {
    List<List<Mention>> copy = new ArrayList<>(mentions.size());
    for (List<Mention> sm:mentions) {
      List<Mention> sm2 = new ArrayList<>(sm.size());
      for (Mention m:sm) {
        Mention m2 = new Mention();
        m2.goldCorefClusterID = m.goldCorefClusterID;
        m2.mentionID = m.mentionID;
        m2.startIndex = m.startIndex;
        m2.endIndex = m.endIndex;
        m2.originalSpan = m.originalSpan;
        m2.dependency = m.dependency;

View on GitHub (pinned to 1b7edd19c4)