stanfordnlp/CoreNLP · error · RuntimeException

Incompatible CRFClassifier: pad does not match

Error message

Incompatible CRFClassifier: pad does not match

What it means

combine() first checks the two CRFClassifiers are compatible; the 'pad' string (used to pad out-of-range context in windowed features) must be identical. Different pad values would make feature names from the two models inconsistent, so the merge is refused with a RuntimeException.

Solutions

  1. Retrain the models with the same pad setting (flags.pad) before combining.
  2. Check and align SeqClassifierFlags between the two training runs.
  3. If pads only differ cosmetically and feature suffixes are unaffected, consider editing flags rather than code — but the safe fix is retraining with matching flags.

Example fix

// before: train modelB with -pad "##"
// after: train both models with identical flags, e.g.
props.setProperty("pad", "-LRB-"); // same value for both training runs
Defensive patterns

Strategy: validation

Validate before calling

if (!modelA.pad.equals(modelB.pad))
  throw new IllegalStateException("pad differs: " + modelA.pad + " vs " + modelB.pad);

Prevention

When it happens

Trigger: classifierA.combine(classifierB) where this.pad != crf.pad — the models were trained with different SeqClassifierFlags.pad values (or one was trained with the default and the other with a custom pad).

Common situations: Merging models trained under different flag configurations; copying flags incompletely between training runs; mixing serialized models from different projects.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/4b3439de81adbb57. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/ie/crf/CRFClassifier.java:355

        CRFLabel newLabels = crfLabelMap.get(labels);
        int k = this.labelIndices.get(featureTypeIndex).indexOf(newLabels);
        weights[newIndex][k] += crf.weights[i][j] * weight;
      }
    }
  }

  /**
   * Combines weighted crf with this crf.
   *
   * @param crf Other CRF whose weights to combine into this CRF
   * @param weight Amount to scale the other CRF's weights by
   */
  public void combine(CRFClassifier<IN> crf, double weight) {
    Timing timer = new Timing();

    // Check the CRFClassifiers are compatible
    if (!this.pad.equals(crf.pad)) {
      throw new RuntimeException("Incompatible CRFClassifier: pad does not match");
    }
    if (this.windowSize != crf.windowSize) {
      throw new RuntimeException("Incompatible CRFClassifier: windowSize does not match");
    }
    if (this.labelIndices.size() != crf.labelIndices.size()) {
      // Should match since this should be same as the windowSize
      throw new RuntimeException("Incompatible CRFClassifier: labelIndices length does not match");
    }
    this.classIndex.addAll(crf.classIndex.objectsList());

    // Combine weights of the other classifier with this classifier,
    // weighing the other classifier's weights by weight
    // First merge the feature indices
    int oldNumFeatures1 = this.featureIndex.size();
    int oldNumFeatures2 = crf.featureIndex.size();
    int oldNumWeights1 = this.getNumWeights();
    int oldNumWeights2 = crf.getNumWeights();
    this.featureIndex.addAll(crf.featureIndex.objectsList());

View on GitHub (pinned to 1b7edd19c4)