stanfordnlp/CoreNLP · error

Could not save model to stream!

Error message

Could not save model to stream!

What it means

SimpleSentiment.train serializes the trained classifier to an ObjectOutputStream wrapped around the modelLocation stream when -serializeTo/-serialize model output is provided. If writing or closing the object stream throws IOException, it logs this terse message. The model is not persisted even though training succeeded, so later load attempts will fail with no file.

Solutions

  1. Check the serialization path: directory exists, file writable, sufficient disk space.
  2. Fix any IOException detail available (enable fuller logging) to distinguish open vs write vs close failures.
  3. Write to a temp file then atomically move it into place to avoid partial model files.
  4. If the stream is provided by a lambda/supplier, ensure it is open and not already consumed/closed before writeObject.

Example fix

// before: directory doesn't exist
java -cp ... SimpleSentiment -trainPath train.txt -serialize /nonexistent/dir/model.ser
// after
mkdir -p models
java -cp ... SimpleSentiment -trainPath train.txt -serialize models/model.ser
Defensive patterns

Strategy: try-catch

Validate before calling

Path out = Paths.get(serializeTo);
if (out.getParent() != null) Files.createDirectories(out.getParent());
if (!Files.isWritable(out.getParent())) throw new IOException("Not writable: " + out.getParent());

Try / catch

try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(out))) {
    oos.writeObject(classifier);
} catch (IOException e) {
    throw new UncheckedIOException("Failed to serialize model to " + out, e);
}

Prevention

When it happens

Trigger: Within train(), constructing ObjectOutputStream or calling writeObject/close on the stream from modelLocation throws IOException — e.g. unwritable destination path, full disk, stream closed early, or the underlying OutputStream supplier failing.

Common situations: Serialize target in a read-only directory; typo'd path in a non-existent directory; disk quota exceeded in CI; running in a container with a read-only filesystem mounting the output path.

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/f30e845374e4427e. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/sentiment/SimpleSentiment.java:270

        if (useL1) {
          minimizer.useOWLQN(true, 1 / (sigma * sigma));
        } else {
          factory.setSigma(sigma);
        }
        return minimizer;
      });
    } catch (Exception ignored) {}
    factory.setSigma(sigma);
    LinearClassifier<SentimentClass, String> classifier = factory.trainClassifier(dataset);

    // Optionally save the model
    modelLocation.ifPresent(stream -> {
      try {
        ObjectOutputStream oos = new ObjectOutputStream(stream);
        oos.writeObject(classifier);
        oos.close();
      } catch (IOException e) {
        log.err("Could not save model to stream!");
      }
    });
    endTrack("Training");

    // Evaluate the model
    forceTrack("Evaluating");
    factory.setVerbose(false);
    double sumAccuracy = 0.0;
    Counter<SentimentClass> sumP = new ClassicCounter<>();
    Counter<SentimentClass> sumR = new ClassicCounter<>();
    int numFolds = 4;
    for (int fold = 0; fold < numFolds; ++fold) {
      Pair<GeneralDataset<SentimentClass, String>, GeneralDataset<SentimentClass, String>> trainTest = dataset.splitOutFold(fold, numFolds);
      LinearClassifier<SentimentClass, String> foldClassifier = factory.trainClassifierWithInitialWeights(trainTest.first, classifier);  // convex objective, so this should be OK
      sumAccuracy += foldClassifier.evaluateAccuracy(trainTest.second);
      for (SentimentClass label : SentimentClass.values()) {
        Pair<Double, Double> pr = foldClassifier.evaluatePrecisionAndRecall(trainTest.second, label);
        sumP.incrementCount(label, pr.first);

View on GitHub (pinned to 1b7edd19c4)