stanfordnlp/CoreNLP · error · IllegalArgumentException

numClasses must be 2, 3, or 5

Error message

numClasses must be 2, 3, or 5

What it means

IllegalArgumentException from ReadSentimentDataset.main when -numClasses is given a value other than 2, 3, or 5; the sentiment dataset reader only supports binary, 3-class, and the standard 5-class SST splits.

Solutions

  1. Use -numClasses 2, 3, or 5 only
  2. Omit the flag if the default is acceptable
  3. Change model code if you truly need a different class count (not just the flag)

Example fix

// before
-numClasses 4
// after
-numClasses 5
Defensive patterns

Strategy: validation

Validate before calling

if (numClasses != 2 && numClasses != 3 && numClasses != 5) throw new IllegalArgumentException("numClasses must be 2, 3, or 5");

Try / catch

try { ReadSentimentDataset.main(args); } catch (IllegalArgumentException e) { if (e.getMessage().contains("numClasses")) { System.err.println("Use -numClasses 2, 3, or 5"); } else throw e; }

Prevention

When it happens

Trigger: Passing e.g. -numClasses 4 or -numClasses 0 on the command line when converting the dataset.

Common situations: Users assuming arbitrary class counts are supported, or converting binary SST variants with an invalid intermediate number.

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

Appendix: source

Thrown at src/edu/stanford/nlp/sentiment/ReadSentimentDataset.java:387

    String dictionaryFilename = null;
    String sentimentFilename = null;
    String tokensFilename = null;
    String parseFilename = null;
    String splitFilename = null;

    String trainFilename = null;
    String devFilename = null;
    String testFilename = null;

    int numClasses = 5;

    // find numClasses first so we can dynamically change the names of
    // the ouput files
    for (int argIndex = 0; argIndex < args.length; ++argIndex) {
      if (args[argIndex].equalsIgnoreCase("-numClasses")) {
        numClasses = Integer.parseInt(args[argIndex + 1]);
        if (numClasses != 2 && numClasses != 3 && numClasses != 5) {
          throw new IllegalArgumentException("numClasses must be 2, 3, or 5");
        }
        break;
      }
    }

    int argIndex = 0;
    while (argIndex < args.length) {
      if (args[argIndex].equalsIgnoreCase("-dictionary")) {
        dictionaryFilename = args[argIndex + 1];
        argIndex += 2;
      } else if (args[argIndex].equalsIgnoreCase("-sentiment")) {
        sentimentFilename = args[argIndex + 1];
        argIndex += 2;
      } else if (args[argIndex].equalsIgnoreCase("-tokens")) {
        tokensFilename = args[argIndex + 1];
        argIndex += 2;
      } else if (args[argIndex].equalsIgnoreCase("-parse")) {
        parseFilename = args[argIndex + 1];

View on GitHub (pinned to 1b7edd19c4)