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
- Ensure every startTrack(title) has exactly one matching endTrack(title) on all control-flow paths (finally block)
- Reconfigure handlers only when no track is open (Redwood.depth == 0)
- Check for start/end calls issued to different handler sets after RedwoodConfiguration.apply(...)
- 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
- Pair every startTrack with endTrack in try/finally
- Only reconfigure logging handlers when Redwood.depth == 0
- Avoid mixing multiple handler-configuration styles (RedwoodConfiguration.apply vs manual addChild)
- Check that all code paths (including exceptions) reaching endTrack had a matching startTrack
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
- Cannot modify Redwood when within a track
- Called remove() before any elements returned
- Cannot nest Redwood threaded environments
- Must capture one of stderr or stdout
- Attempt to create ChineseSimWordAvgDepGrammar before…
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)