stanfordnlp/CoreNLP · error · RuntimeException
Label dictionary is already locked.
Error message
Label dictionary is already locked.
What it means
LabelDictionary supports a two-phase lifecycle: collect observation counts via increment(), then freeze them via lock(). Once lock() has run, labelDictionary is non-null and no further observations may be recorded, because the constrained label sets are already materialized. Calling increment after that point throws this RuntimeException.
Solutions
- Create a new LabelDictionary for each collection phase; call lock() only after all increment() calls are done.
- Restructure the pipeline so lock() is the last step before CRF training begins.
- If you need to add data after locking, rebuild the dictionary: new LabelDictionary, re-increment everything, lock again.
Example fix
// before
dict.increment("foo", "LOC"); // after lock() already ran -> throws
// after
LabelDictionary dict2 = new LabelDictionary(); // fresh instance for new data
dict2.increment("foo", "LOC");
dict2.lock(threshold, labelIndex); Defensive patterns
Strategy: try-catch
Validate before calling
// Java: guard before incrementing
boolean locked;
try {
java.lang.reflect.Field f = LabelDictionary.class.getDeclaredField("labelDictionary");
f.setAccessible(true);
locked = f.get(dict) != null;
} catch (Exception e) { locked = false; }
if (!locked) dict.increment(observation, label); Try / catch
// Java
try {
dict.increment(observation, label);
} catch (RuntimeException e) {
if (e.getMessage().contains("already locked")) {
dict = new LabelDictionary(); // restart collection phase
dict.increment(observation, label);
} else throw e;
} Prevention
- Treat LabelDictionary as single-use: increment phase, then lock, then discard.
- Call lock() only after the entire dataset has been scanned.
- Never share one dictionary across sequential training runs.
When it happens
Trigger: Calling increment(observation, label) after lock(threshold, labelIndex) has already been called on the same LabelDictionary instance — e.g. training a second dataset with a dictionary that was locked for the first, or calling increment inside an loop that runs after lock.
Common situations: Reusing a LabelDictionary across multiple training runs; pipeline code that calls lock() for CRF feature setup and then continues accumulating observations; adding new training data to an already-locked dictionary.
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
- Label dictionary is already locked
- after W derivative, index() != x.length()
- conditionalLogProbGivenFirst requires of one less than…
- conditionalLogProbGivenNext requires given one less than…
- conditionalLogProbGivenPrevious requires given one less…
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/73b904ae4556155c.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/ie/crf/LabelDictionary.java:60
private int[][] labelDictionary;
/**
* Constructor.
*/
public LabelDictionary() {
this.observationCounts = new ClassicCounter<>(DEFAULT_CAPACITY);
this.observedLabels = Generics.newHashMap(DEFAULT_CAPACITY);
}
/**
* Increment counts for an observation/label pair.
*
* @param observation
* @param label
*/
public void increment(String observation, String label) {
if (labelDictionary != null) {
throw new RuntimeException("Label dictionary is already locked.");
}
observationCounts.incrementCount(observation);
if ( ! observedLabels.containsKey(observation)) {
observedLabels.put(observation, new HashSet<>());
}
observedLabels.get(observation).add(label.intern());
}
/**
* True if this observation is constrained, and false otherwise.
*/
public boolean isConstrained(String observation) {
return observationIndex.indexOf(observation) >= 0;
}
/**
* Get the allowed label set for an observation.
*View on GitHub (pinned to 1b7edd19c4)