stanfordnlp/CoreNLP · error · RuntimeException

after blockInitialize, param Index ( ) not equal to…

Error message

after blockInitialize, param Index ( ) not equal to beforeOutputWeights ( )

What it means

During parameter initialization, the non-linear CRF objective pre-fills parameters up to beforeOutputWeights via blockInitialize. It then asserts the count of filled slots equals beforeOutputWeights; if not, an internal bookkeeping bug (wrong block sizes, mismatched layer dimensions) is reported with this RuntimeException showing both counts.

Solutions

  1. Check the RuntimeException numbers: if count < beforeOutputWeights, some block-initialize branch was skipped — inspect which flags gated it.
  2. Use a standard flag combination (e.g. default inputLayerSize = numClasses with output layer disabled, or softmax+sparse) known to initialize correctly.
  3. Verify inputLayerSize/hidden layer sizes are set consistently with numClasses and the feature map.
  4. If you modified the source, fix blockInitialize so its inner loop counts match the beforeOutputWeights offset computation.
  5. Report the exact flag combination to the Stanford NLP maintainers if stock flags reproduce it.

Example fix

// before
flags.softmaxOutputLayer = true;
flags.sparseOutputLayer = false;
flags.tieOutputLayer = false; // inconsistent block layout
// after
flags.softmaxOutputLayer = true;
flags.sparseOutputLayer = true; // consistent block-initialize path
Defensive patterns

Strategy: validation

Validate before calling

if (flags.useOutputLayer && !(flags.sparseOutputLayer || flags.tieOutputLayer || flags.softmaxOutputLayer))
  throw new IllegalArgumentException("unsupported output-layer flag combination for blockInitialize");

Type guard

static boolean standardOutputFlags(SeqClassifierFlags f) { return !f.useOutputLayer || f.sparseOutputLayer || f.tieOutputLayer; }

Try / catch

try {
  double[] x = crf.initial();
} catch (RuntimeException e) {
  if (e.getMessage().contains("after blockInitialize")) {
    log.error("blockInitialize invariant broken; check layer dims/flags");
    flags.inputLayerSize = flags.numClasses; // fall back to standard layout
  } else throw e;
}

Prevention

When it happens

Trigger: Calling initial() with a flag/dimension combination (inputLayerSize, numClasses, useOutputLayer, sparse/tie modes) whose blockInitialize loop fills fewer or more entries than beforeOutputWeights — i.e. the block initializer and the computed offsets disagree.

Common situations: Non-standard combinations of useOutputLayer, sparseOutputLayer, tieOutputLayer, and inputLayerSize that the block initializer does not handle; custom patches or version mismatches in the objective function code.

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

Appendix: source

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

        double twoFanIn = 2.0 * fanIn;
        int interval = numNodeFeatures / numHiddenUnits;
        for (int i = 0; i < numHiddenUnits; i++) {
          int lower = i * interval;
          int upper = (i + 1) * interval;
          if (i == numHiddenUnits - 1)
            upper = numNodeFeatures;
          for (int j = 0; j < outputLayerSize; j++) {
            for (int k = 0; k < numNodeFeatures; k++) {
              val = 0;
              if (k >= lower && k < upper) {
                val = random.nextDouble() * twoFanIn - fanIn;
              }
              initial[count++] = val;
            }
          }
        }
        if (count != beforeOutputWeights) {
          throw new RuntimeException("after blockInitialize, param Index (" + count + ") not equal to beforeOutputWeights (" + beforeOutputWeights + ")");
        }
      } else {
        double fanIn = 1 / Math.sqrt(numNodeFeatures+0.0);
        double twoFanIn = 2.0 * fanIn;
        for (int i = edgeParamCount; i < beforeOutputWeights; i++) {
          val = random.nextDouble() * twoFanIn - fanIn;
          initial[count++] = val;
        }
      }

      // init output layer weights
      if (flags.sparseOutputLayer) {
        for (int i = 0; i < outputLayerSize; i++) {
          double total = 1;
          for (int j = 0; j < numHiddenUnits-1; j++) {
            val = random.nextDouble() * total;
            initial[count++] = val;
            total -= val;

View on GitHub (pinned to 1b7edd19c4)