stanfordnlp/CoreNLP · error · UnsupportedOperationException

segmentWords must be run first

Error message

segmentWords must be run first

What it means

MaxMatchSegmenter.segmentWords(MatchHeuristic) performs dynamic programming over the segmentation lattice, which must first be built by a previous call. If the lattice is null or len < 0, the method throws UnsupportedOperationException because there is nothing to segment.

Solutions

  1. Call the lattice-building step (buildSegmentationLattice / maxMatchSegmentation) before segmentWords
  2. Restructure code so segmentWords is only invoked after successful lattice construction
  3. Check lattice state before calling and rebuild if null

Example fix

// before
List<Word> words = segmenter.segmentWords(MatchHeuristic.MAX_WORDS);
// after
segmenter.buildSegmentationLattice(sentence);
List<Word> words = segmenter.segmentWords(MatchHeuristic.MAX_WORDS);
Defensive patterns

Strategy: validation

Validate before calling

if (segmenterLatticeReady == false) {
  segmenter.buildSegmentationLattice(sentence);
}
List<Word> words = segmenter.segmentWords(heuristic);

Try / catch

try {
  words = segmenter.segmentWords(h);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("must be run first")) {
    segmenter.buildSegmentationLattice(sentence);
    words = segmenter.segmentWords(h);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling segmentWords(h) before buildSegmentationLattice (or before the internal lattice-producing pass) has been invoked, or calling it a second time after state was reset.

Common situations: Using MaxMatchSegmenter programmatically and calling the DP method directly instead of going through the driver that builds the lattice first; calling main-style flows out of order.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at src/edu/stanford/nlp/wordseg/MaxMatchSegmenter.java:202

  public ArrayList<Word> maxMatchSegmentation() {
    return segmentWords(MatchHeuristic.MINWORDS);
  }

  /**
   * Returns the lexicon-based segmentation following heuristic h.
   * Note that buildSegmentationLattice must be run first.
   * Two heuristics are currently available -- MINWORDS and MAXWORDS --
   * to respectively minimize and maximize the number of segment
   * (where each segment is a lexicon word, if possible).
   *
   * @param h Heuristic to use for segmentation.
   * @return Segmented sentence.
   * @throws UnsupportedOperationException
   * @see #buildSegmentationLattice
   */
  public ArrayList<Word> segmentWords(MatchHeuristic h) throws UnsupportedOperationException {
    if(lattice==null || len < 0)
      throw new UnsupportedOperationException("segmentWords must be run first");
    List<Word> segmentedWords = new ArrayList<>();
    // Init dynamic programming:
    double[] costs = new double[len+1];
    List<DFSATransition<Word, Integer>> bptrs = new ArrayList<>();
    for (int i = 0; i < len + 1; ++i) {
      bptrs.add(null);
    }
    costs[0]=0.0;
    for (int i=1; i<=len; ++i)
       costs[i] = Double.MAX_VALUE;
    // DP:
    for (int start=0; start<len; ++start) {
      DFSAState<Word, Integer> fromState = states.get(start);
      Collection<DFSATransition<Word, Integer>> trs = fromState.transitions();
      for (DFSATransition<Word, Integer> tr : trs) {
        DFSAState<Word, Integer> toState = tr.getTarget();
        double lcost = tr.score();
        int end = toState.stateID();

View on GitHub (pinned to 1b7edd19c4)