stanfordnlp/CoreNLP · error · RuntimeException

after edge derivative, index() != edgeParamCount()

Error message

after edge derivative, index() != edgeParamCount()

What it means

While filling the gradient array in CRFNonLinearLogConditionalObjectiveFunction.calculate(), the running write index did not land exactly on edgeParamCount after writing all edge (first-order) derivative terms. This is an internal layout invariant: each derivative slot must be written exactly once, so a mismatch means the parameter layout constants disagree with the loop bounds.

Solutions

  1. Verify that the data/labels/map/labelIndices passed to the constructor are the ones produced by the standard CRFLogConditionalObjectiveFunction feature indexing.
  2. Check for local modifications to the derivative-filling loops and restore them so exactly edgeParamCount entries are written for edges.
  3. Update to an official Stanford CoreNLP release if working from a patched copy.
  4. Ensure window size and numEdgeFeatures are consistent with second-order (window) labeling assumptions.

Example fix

// before (patched loop writes fewer entries)
for (int i = 0; i < E.length - 1; i++) {
  for (int j = 0; j < E[i].length; j++) derivative[index++] = E[i][j] - Ehat[i][j];
}
// after (write the full edge block)
for (int i = 0; i < E.length; i++) {
  for (int j = 0; j < E[i].length; j++) derivative[index++] = E[i][j] - Ehat[i][j];
}
Defensive patterns

Strategy: validation

Validate before calling

// assert layout before training
int expected = fn.domainDimension();
if (derivative.length != expected)
  throw new IllegalStateException("derivative length " + derivative.length + " != domainDimension " + expected);

Try / catch

try {
  minimizer.minimize(fn, tol, x);
} catch (RuntimeException e) {
  if (e.getMessage().startsWith("after edge derivative")) {
    // fall back to standard (linear) CRF training
  } else throw e;
}

Prevention

When it happens

Trigger: A mismatch between numEdgeFeatures/edgeParamCount and the loops filling E/Ehat derivatives -- e.g. custom code that altered the 'map', labelIndices, or data dimensions passed to the constructor so the edge loops write more or fewer entries than edgeParamCount.

Common situations: Developers subclassing or modifying the non-linear CRF code (changing window size, label indices, or feature map) hit the inconsistency during CRF training with useNonLinearCRF=true; also possible in NER training pipelines with non-standard feature maps.

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/bb234924a2410274. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/ie/crf/CRFNonLinearLogConditionalObjectiveFunction.java:690

    value = -prob;
    if(VERBOSE){
      log.info("value is " + value);
    }

    if (DEBUG) log.info("calculating derivative ");
    // compute the partial derivative for each feature by comparing expected counts to empirical counts
    int index = 0;
    for (int i = 0; i < E.length; i++) {
      for (int j = 0; j < E[i].length; j++) {
        derivative[index++] = (E[i][j] - Ehat[i][j]);
        if (VERBOSE) {
          log.info("linearWeights deriv(" + i + "," + j + ") = " + E[i][j] + " - " + Ehat[i][j] + " = " + derivative[index - 1]);
        }
      }
    }
    if (index != edgeParamCount)
      throw new RuntimeException("after edge derivative, index("+index+") != edgeParamCount("+edgeParamCount+")");

    for (int i = 0; i < eW.length; i++) {
      for (int j = 0; j < eW[i].length; j++) {
        derivative[index++] = (eW[i][j] - What[i][j]);
        if (VERBOSE) {
          log.info("inputLayerWeights deriv(" + i + "," + j + ") = " + eW[i][j] + " - " + What[i][j] + " = " + derivative[index - 1]);
        }
      }
    }

    if (index != beforeOutputWeights)
      throw new RuntimeException("after W derivative, index("+index+") != beforeOutputWeights("+beforeOutputWeights+")");

    if (useOutputLayer) {
      for (int i = 0; i < eU.length; i++) {
        for (int j = 0; j < eU[i].length; j++) {
          if (flags.hardcodeSoftmaxOutputWeights)
            derivative[index++] = 0;

View on GitHub (pinned to 1b7edd19c4)