{"record":{"id":"e532683fdd14628f","repo":"stanfordnlp/CoreNLP","slug":"not-training-or-training-was-already-finalized","errorCode":null,"errorMessage":"Not training, or training was already finalized","messagePattern":"Not training, or training was already finalized","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/parser/nndep/Classifier.java","lineNumber":630,"sourceCode":"    eg2E = new double[E.length][E[0].length];\n    eg2W1 = new double[W1.length][W1[0].length];\n    eg2b1 = new double[b1.length];\n    eg2W2 = new double[W2.length][W2[0].length];\n  }\n\n  /**\n   * Clear all gradient histories used for AdaGrad training.\n   *\n   * @throws java.lang.IllegalStateException If not training\n   */\n  public void clearGradientHistories() {\n    validateTraining();\n    initGradientHistories();\n  }\n\n  private void validateTraining() {\n    if (!isTraining)\n      throw new IllegalStateException(\"Not training, or training was already finalized\");\n  }\n\n  /**\n   * Finish training this classifier; prepare for a shutdown.\n   */\n  public void finalizeTraining() {\n    validateTraining();\n\n    // Destroy threadpool\n    jobHandler.join(true);\n\n    isTraining = false;\n  }\n\n  /**\n   * @see #preCompute(java.util.Set)\n   */\n  public void preCompute() {","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/parser/nndep/Classifier.java#L612-L648","documentation":"Classifier (nndep) methods that mutate training state (like validateTraining callers: initGradientHistories, preTraining, etc.) require the classifier to be in training mode. The private validateTraining() throws IllegalStateException when isTraining is false, i.e. training never started or finalizeTraining() was already called (which flips training mode off).","triggerScenarios":"Calling training-time methods (e.g. Classifier's constructor path calling initGradientHistories, or addSample/gradient updates) after finalizeTraining() or on a classifier constructed for inference only.","commonSituations":"Calling finalizeTraining() twice; resuming training on a loaded model without re-entering training mode; invoking training APIs from a script after training loop completed.","solutions":["Ensure training is started (training mode enabled) before calling training methods","Do not call finalizeTraining() until all training iterations are complete; never call it twice","Re-train or construct a new classifier instance if you already finalized training and need to train more"],"exampleFix":"// before\nclassifier.finalizeTraining();\nclassifier.addSample(data); // throws\n// after\nclassifier.addSample(data); // while still training\nclassifier.finalizeTraining(); // only once, at the very end","handlingStrategy":"validation","validationCode":"// call training APIs only before finalizeTraining()\nif (trainingDone) throw new IllegalStateException(\"Training already finalized\");\nclassifier.addSample(sample);","typeGuard":null,"tryCatchPattern":"try {\n  classifier.addSample(sample);\n} catch (IllegalStateException e) {\n  // recreate classifier or restart training\n}","preventionTips":["Track training lifecycle with a boolean in your trainer loop","Call finalizeTraining exactly once at the end","Never mix inference and training calls on the same instance after finalization"],"tags":["java","illegal-state","nndep","ml"],"backgroundTag":"invalid-state-transition","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"}