stanfordnlp/CoreNLP · error · RuntimeException
Extractors can't both be local and dynamic!
Error message
Extractors can't both be local and dynamic!
What it means
Extractors.initTypes classifies each Extractor as local (depends only on the local sentence window) or dynamic (stateful across the sequence). An extractor reporting both isLocal() and isDynamic() is a contradiction and triggers this RuntimeException. It guards an internal invariant of the feature extraction model.
Solutions
- Fix the custom extractor so exactly one of isLocal()/isDynamic() returns true (typically local=true, dynamic=false)
- If the extractor needs cross-position state, make it dynamic only (isLocal()=false, isDynamic()=true)
- Check the Extractor superclass defaults and only override what you need
- If loading an old model file, retrain with extractors from the same library version
Example fix
// before
@Override public boolean isLocal() { return true; }
@Override public boolean isDynamic() { return true; } // contradiction
// after
@Override public boolean isLocal() { return true; }
@Override public boolean isDynamic() { return false; } Defensive patterns
Strategy: validation
Validate before calling
for (Extractor e : extractors) {
if (e.isLocal() && e.isDynamic()) {
throw new IllegalArgumentException("Extractor must be local or dynamic, not both: " + e.getClass().getName());
}
} Try / catch
try {
new Extractors(extractorArray);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().equals("Extractors can't both be local and dynamic!")) {
// find and fix the offending extractor's isLocal/isDynamic overrides
} else { throw e; }
} Prevention
- In custom Extractor subclasses, return true for exactly one of isLocal/isDynamic
- Rely on the Extractor superclass defaults instead of overriding both flags
- Validate extractor arrays programmatically before constructing Extractors
- Retrain models when upgrading across versions with changed extractor defaults
When it happens
Trigger: Building an Extractors instance (e.g. via new Extractors(Extractor[])) containing a custom extractor whose isLocal() and isDynamic() both return true; loading a serialized model with such an extractor.
Common situations: Writing a custom Extractor subclass and overriding isLocal()/isDynamic() incorrectly (e.g. returning true in both); mixing extractors from incompatible code versions where defaults changed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- adjustFinalToken: Unexpected final char: |
- At least two of lang (" + lang + "), openClassTags (length…
- can't open file
- Coordination node must have at least 2 children.
- Couldn't create POS tagger extractor class
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/75ecc860cdb0f13f.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/tagger/maxent/Extractors.java:57
v = new Extractor[extrs.length];
System.arraycopy(extrs, 0, v, 0, extrs.length);
initTypes();
}
/**
* Determine type of each feature extractor.
*/
void initTypes() {
local = new ArrayList<>();
localContext = new ArrayList<>();
dynamic = new ArrayList<>();
for(int i=0; i<v.length; ++i) {
Extractor e = v[i];
if(e.isLocal() && e.isDynamic())
throw new RuntimeException("Extractors can't both be local and dynamic!");
if(e.isLocal()) {
local.add(Pair.makePair(i,e));
//localContext.put(i,e);
} else if(e.isDynamic()) {
dynamic.add(Pair.makePair(i,e));
} else {
localContext.add(Pair.makePair(i,e));
}
}
if(DEBUG) {
log.info("Extractors: " + this);
log.info("Local: " + local.size() + " extractors");
log.info("Local context: " + localContext.size() + " extractors");
log.info("Dynamic: " + dynamic.size() + " extractors");
}
}
/**View on GitHub (pinned to 1b7edd19c4)