stanfordnlp/CoreNLP · error · IllegalStateException

Invalid classifier label for isDone: " + argmax

Error message

Invalid classifier label for isDone: " + argmax

What it means

State.withIsDone() accepts only the CLAUSE_SPLIT or CLAUSE_INTERM labels when updating a search state's isDone flag. Any other label (e.g. CLAUSE_NOT_MERGE or null) is unsupported for this transition, so the code fails fast with an IllegalStateException. It is an internal invariant check inside the clause-splitting search, not something callers normally control directly.

Solutions

  1. Load a valid, trained clause splitter model so the classifier only emits CLAUSE_SPLIT/CLAUSE_INTERM/CLAUSE_NOT_MERGE appropriately.
  2. Check the caller that computes the argmax label and ensure it maps all classifier outcomes to valid ClauseClassifierLabel values.
  3. If you invoke withIsDone yourself, guard against null and map any label that is neither SPLIT nor INTERM to CLAUSE_NOT_MERGE instead.

Example fix

// before
state.withIsDone(label);
// after
ClauseClassifierLabel safe = label == null ? ClauseClassifierLabel.CLAUSE_NOT_MERGE : label;
if (safe == ClauseClassifierLabel.CLAUSE_SPLIT || safe == ClauseClassifierLabel.CLAUSE_INTERM) {
  state.withIsDone(safe);
}
Defensive patterns

Strategy: validation

Validate before calling

if (label != ClauseClassifierLabel.CLAUSE_SPLIT && label != ClauseClassifierLabel.CLAUSE_INTERM) {
  throw new IllegalArgumentException("withIsDone requires SPLIT or INTERM, got: " + label);
}

Type guard

boolean isValidForIsDone(ClauseClassifierLabel l) { return l == ClauseClassifierLabel.CLAUSE_SPLIT || l == ClauseClassifierLabel.CLAUSE_INTERM; }

Try / catch

try {
  state.withIsDone(label);
} catch (IllegalStateException e) {
  log.warn("Skipping invalid isDone label", e);
}

Prevention

When it happens

Trigger: Calling withIsDone with a ClauseClassifierLabel other than CLAUSE_SPLIT or CLAUSE_INTERM — typically CLAUSE_NOT_MERGE — or null, which can happen if the clause classifier's weight vector is empty/untrained and argmax resolution yields an unexpected label during search.

Common situations: Running ClauseSplitter/OpenIE with a missing, corrupt, or empty splitter model so the classifier's argmax returns a label the state machine doesn't handle; custom code that constructs classifier labels manually.

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

Appendix: source

Thrown at src/edu/stanford/nlp/naturalli/ClauseSplitterSearchProblem.java:183

      this.edgeIndex = edgeToIndex.indexOf(edge);
      this.subjectOrNull = source.subjectOrNull;
      this.distanceFromSubj = source.distanceFromSubj;
      this.objectOrNull = source.objectOrNull;
      this.thunk = source.thunk;
      this.isDone = isDone;
    }

    public SemanticGraph originalTree() {
      return ClauseSplitterSearchProblem.this.tree;
    }

    public State withIsDone(ClauseClassifierLabel argmax) {
      if (argmax == ClauseClassifierLabel.CLAUSE_SPLIT) {
        isDone = true;
      } else if (argmax == ClauseClassifierLabel.CLAUSE_INTERM) {
        isDone = false;
      } else {
        throw new IllegalStateException("Invalid classifier label for isDone: " + argmax);
      }
      return this;
    }
  }

  /**
   * An action being taken; that is, the type of clause splitting going on.
   */
  public interface Action {
    /**
     * The name of this action.
     */
    String signature();

    /**
     * A check to make sure this is actually a valid action to take, in the context of the given tree.
     * @param originalTree The _original_ tree we are searching over. This is before any clauses are split off.
     * @param edge The edge that we are traversing with this clause.

View on GitHub (pinned to 1b7edd19c4)