stanfordnlp/CoreNLP · error · RuntimeException

Invalid classifier type: ${relationExtractorClassifierType}

Error message

Invalid classifier type: ${relationExtractorClassifierType}

What it means

In BasicRelationExtractor.trainMulticlass, the configured relationExtractorClassifierType selects a factory for training the relation classifier. Only "loglinear" (logistic) and "svm" branches exist; any other value (case-insensitive comparison) falls into the final else and throws RuntimeException. It is a configuration error: the chosen classifier family is not implemented/supported by this trainer.

Solutions

  1. Set the classifier-type property to exactly "loglinear" (logistic regression) or "svm" (SVMLight).
  2. Check for typos, extra whitespace, or wrong case-sensitivity assumptions in the config value.
  3. Read BasicRelationExtractor.java to confirm which types your version supports, and add a new factory branch if you need another learner.
  4. Log/echo the property value at startup so a misconfigured value surfaces before training starts.

Example fix

// before (properties)
relation.extractor.classifierType = maxent
// after
relation.extractor.classifierType = loglinear
Defensive patterns

Strategy: validation

Validate before calling

String type = props.getProperty("relation.extractor.classifierType");
if (!"loglinear".equalsIgnoreCase(type) && !"svm".equalsIgnoreCase(type)) {
  throw new IllegalArgumentException("classifierType must be 'loglinear' or 'svm', got: " + type);
}

Prevention

When it happens

Trigger: Setting the classifier type property (relationExtractorClassifierType) to anything other than "loglinear" or "svm" (e.g. "naivebayes", "logistic", "SVM " with trailing whitespace, or a typo) before calling train()/trainMulticlass().

Common situations: Typing the classifier name by hand in the training properties file; copying a config from a different NLP pipeline that supports more classifier types; assuming case or synonyms like "maxent" are accepted; upgrading CoreNLP and renaming the option.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/ie/machinereading/BasicRelationExtractor.java:122

    GeneralDataset<String, String> trainSet = createDataset(sentences);
    trainMulticlass(trainSet);
  }

  public void trainMulticlass(GeneralDataset<String, String> trainSet) {
    if (relationExtractorClassifierType.equalsIgnoreCase("linear")) {
      LinearClassifierFactory<String, String> lcFactory = new LinearClassifierFactory<>(1e-4, false, sigma);
      lcFactory.setVerbose(false);
      // use in-place SGD instead of QN. this is faster but much worse!
      // lcFactory.useInPlaceStochasticGradientDescent(-1, -1, 1.0);
      // use a hybrid minimizer: start with in-place SGD, continue with QN
      // lcFactory.useHybridMinimizerWithInPlaceSGD(50, -1, sigma);
      classifier = lcFactory.trainClassifier(trainSet);
    } else if (relationExtractorClassifierType.equalsIgnoreCase("svm")) {
      SVMLightClassifierFactory<String, String> svmFactory = new SVMLightClassifierFactory<>();
      svmFactory.setC(sigma);
      classifier = svmFactory.trainClassifier(trainSet);
    } else {
      throw new RuntimeException("Invalid classifier type: " + relationExtractorClassifierType);
    }
    if (logger.isLoggable(Level.FINE)) {
      reportWeights(classifier, null);
    }
  }

  protected static void reportWeights(LinearClassifier<String, String> classifier, String classLabel) {
    if (classLabel != null) logger.fine("CLASSIFIER WEIGHTS FOR LABEL " + classLabel);
    Map<String, Counter<String>> labelsToFeatureWeights = classifier.weightsAsMapOfCounters();
    List<String> labels = new ArrayList<>(labelsToFeatureWeights.keySet());
    Collections.sort(labels);
    for (String label: labels) {
      Counter<String> featWeights = labelsToFeatureWeights.get(label);
      List<Pair<String, Double>> sorted = Counters.toSortedListWithCounts(featWeights);
      StringBuilder bos = new StringBuilder();
      bos.append("WEIGHTS FOR LABEL ").append(label).append(':');
      for (Pair<String, Double> feat: sorted) {
        bos.append(' ').append(feat.first()).append(':').append(feat.second()+"\n");

View on GitHub (pinned to 1b7edd19c4)