stanfordnlp/CoreNLP · error · IllegalStateException

OutputHandler received endTrack() without matching…

Error message

OutputHandler received endTrack() without matching startTrack() --are your handlers mis-configured?

What it means

Redwood's OutputHandler.signalEndTrack throws IllegalStateException when endTrack() is called but this handler has no currently open TrackInfo, meaning endTrack arrived without a matching startTrack. This indicates logging handlers/channels were configured inconsistently (e.g. one handler received start but another received end).

Solutions

  1. Ensure every startTrack(title) has exactly one matching endTrack(title) on all control-flow paths (finally block)
  2. Reconfigure handlers only when no track is open (Redwood.depth == 0)
  3. Check for start/end calls issued to different handler sets after RedwoodConfiguration.apply(...)
  4. Log Redwood.depth before endTrack calls during debugging to find the unbalanced one

Example fix

// before
Redwood.startTrack("training");
runEpoch(); // may throw -> endTrack skipped
Redwood.endTrack("training");
// after
Redwood.startTrack("training");
try {
  runEpoch();
} finally {
  Redwood.endTrack("training");
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (Redwood.depth == 0) throw new IllegalStateException("endTrack without startTrack");
Redwood.endTrack(title);

Try / catch

try {
  Redwood.endTrack("training");
} catch (IllegalStateException e) {
  log.warn("Unbalanced endTrack: {}", e.getMessage());
  // inspect handler configuration and track depth
}

Prevention

When it happens

Trigger: Calling Redwood.endTrack(title) when no startTrack(title) is active; custom LogRecordHandler pipelines where startTrack was routed to a different handler than endTrack; reusing/clearing handlers mid-track.

Common situations: Library code that opens a track on one code path but ends it on another (early return/exception before endTrack); swapping RedwoodConfiguration handlers between startTrack and endTrack; nested library calls each managing tracks incorrectly.

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

Appendix: source

Thrown at src/edu/stanford/nlp/util/logging/OutputHandler.java:430

    if(info != null){
      this.trackStack.push(info);
    }
    info = new TrackInfo(signal.content.toString(), signal.timesstamp);
    //(force print)
    if(signal.force()){
      updateTracks(signal.depth+1);
    }
    //(return)
    return EMPTY; //don't send extra records
  }

  /** {@inheritDoc} */
  @Override
  public List<Record> signalEndTrack(int newDepth, long timeOfEnd) {
    //(pop info)
    TrackInfo childInfo = this.info;
    if (childInfo == null) {
      throw new IllegalStateException("OutputHandler received endTrack() without matching startTrack() --" +
          "are your handlers mis-configured?");
    }
    if(trackStack.empty()){
      this.info = null;
    } else {
      this.info = this.trackStack.pop();
      this.info.numElementsPrinted += childInfo.numElementsPrinted;
    }
    //(handle track)
    if(this.queuedTracks.isEmpty()){
      StringBuilder b = new StringBuilder();
      if (!this.missingOpenBracket) {
        //(write margin)
        for(int i=0; i<this.leftMargin; i++) {
          b.append(' ');
        }
        //(null content)
        writeContent(newDepth, "", b);

View on GitHub (pinned to 1b7edd19c4)