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

  1. Fix the custom extractor so exactly one of isLocal()/isDynamic() returns true (typically local=true, dynamic=false)
  2. If the extractor needs cross-position state, make it dynamic only (isLocal()=false, isDynamic()=true)
  3. Check the Extractor superclass defaults and only override what you need
  4. 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

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


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)