{"record":{"id":"7b53cac329bdaaeb","repo":"stanfordnlp/CoreNLP","slug":"failed-to-save-classifier","errorCode":null,"errorMessage":"Failed to save classifier","messagePattern":"Failed to save classifier","errorType":"exception","errorClass":"RuntimeIOException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ie/ClassifierCombiner.java","lineNumber":504,"sourceCode":"  @Override\n  public void train(Collection<List<IN>> docs,\n                    DocumentReaderAndWriter<IN> readerAndWriter) {\n    throw new UnsupportedOperationException();\n  }\n\n  // write a ClassifierCombiner to disk, this is based on CRFClassifier code\n  @Override\n  public void serializeClassifier(String serializePath) {\n    log.info(\"Serializing classifier to \" + serializePath + \"...\");\n\n    ObjectOutputStream oos = null;\n    try {\n      oos = IOUtils.writeStreamFromString(serializePath);\n      serializeClassifier(oos);\n      log.info(\"done.\");\n\n    } catch (Exception e) {\n      throw new RuntimeIOException(\"Failed to save classifier\", e);\n    } finally {\n      IOUtils.closeIgnoringExceptions(oos);\n    }\n  }\n\n  // method for writing a ClassifierCombiner to an ObjectOutputStream\n  @Override\n  public void serializeClassifier(ObjectOutputStream oos) {\n    try {\n      // record the properties used to initialize\n      oos.writeObject(initProps);\n      // this is a bit of a hack, but have to write this twice so you can get it again\n      // after you initialize AbstractSequenceClassifier\n      // basically when this is read from the ObjectInputStream, I read it once to call\n      // super(props) and then I read it again so I can set this.initProps\n      // TODO: probably should have AbstractSequenceClassifier store initProps to get rid of this double writing\n      oos.writeObject(initProps);\n      // record the initial loadPaths","sourceCodeStart":486,"sourceCodeEnd":522,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ie/ClassifierCombiner.java#L486-L522","documentation":"serializeClassifier(String) opens an output stream via IOUtils.writeStreamFromString and writes the combined classifier. Any failure during opening the stream or writing the model is wrapped as a RuntimeIOException with this message.","triggerScenarios":"Calling classifier.serializeClassifier(\"/bad/dir/model.ser.gz\") where the target directory does not exist, is not writable, or the path string is not a valid filename/URL for IOUtils.writeStreamFromString.","commonSituations":"Writing to a read-only deployment directory; missing parent directories; running under a user without write permission; disk full during model dump.","solutions":["Create parent directories before serializing: new File(path).getParentFile().mkdirs()","Verify write permission on the target path for the running user","Serialize to a local writable path first, then copy to the final destination","Check the wrapped cause for the underlying IO failure"],"exampleFix":"// before\nclassifier.serializeClassifier(\"out/models/model.ser.gz\"); // RuntimeIOException if out/models missing\n// after\nnew File(\"out/models\").mkdirs();\nclassifier.serializeClassifier(\"out/models/model.ser.gz\");","handlingStrategy":"try-catch","validationCode":"File out = new File(path);\nFile parent = out.getParentFile();\nif (parent != null && !parent.isDirectory() && !parent.mkdirs())\n  throw new IllegalStateException(\"cannot create dir \" + parent);\nif (parent != null && !parent.canWrite()) throw new IllegalStateException(\"not writable: \" + parent);","typeGuard":null,"tryCatchPattern":"try {\n  classifier.serializeClassifier(serializePath);\n} catch (RuntimeIOException e) {\n  log.error(\"model save failed\", e.getCause());\n  throw e;\n}","preventionTips":["mkdirs() parent directories before serializing","Serialize to temp file then atomic rename","Run serialization under a user with write access to the target dir"],"tags":["java","corenlp","serialization","file-write"],"backgroundTag":"file-write-failed","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"}