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
- Verify that the data/labels/map/labelIndices passed to the constructor are the ones produced by the standard CRFLogConditionalObjectiveFunction feature indexing.
- Check for local modifications to the derivative-filling loops and restore them so exactly edgeParamCount entries are written for edges.
- Update to an official Stanford CoreNLP release if working from a patched copy.
- 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
- Do not modify the edge-derivative loops or the map/labelIndices without recomputing edgeParamCount
- Use standard CRF feature-indexing output as constructor input
- Test non-linear CRF changes on a tiny dataset where the invariant fails fast
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
- after W derivative, index() != beforeOutputWeights()
- after W derivative, index() != x.length()
- after W derivative, index() != beforeOutputWeights()
- after blockInitialize, param Index ( ) not equal to…
- gradient check failed
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)