stanfordnlp/CoreNLP · error · ForwardPropagationException

SentimentCostAndGradient: Tree not correctly binarized:...

Error message

SentimentCostAndGradient: Tree not correctly binarized:...

What it means

After classifying a node, the code checks tree structure/labels (e.g. binarization sanity around top-level constituents and CoreLabel types) and throws ForwardPropagationException with a descriptive error buffer when the tree violates model assumptions, here: not correctly binarized / too many top-level constituents.

Solutions

  1. Binarize trees before passing them to the sentiment model (use the same preprocessing as ReadSentimentDataset/convertTrees)
  2. Check the root has exactly one or two children as the model expects
  3. Validate tree structure programmatically before training

Example fix

// before
(ROOT (S (NP ...) (VP ...) (PP ...))) // 3+ branches
// after
(ROOT (S (NP ...) (VP (VP ...) (PP ...)))) // binarized
Defensive patterns

Strategy: validation

Validate before calling

if (root.children().length > 2) throw new IllegalStateException("Tree not correctly binarized: root has " + root.children().length + " children");

Try / catch

try { forwardPropagate(tree); } catch (ForwardPropagationException e) { if (e.getMessage().contains("not correctly binarized")) { binarizeAndRetry(tree); } else throw e; }

Prevention

When it happens

Trigger: Calling forwardPropagate on a tree with more than two children at the root or multiple top-level constituents, i.e. a tree that was never binarized for the sentiment model.

Common situations: Feeding raw parser output or non-binarized treebank trees directly into SentimentTraining/ExternalEvaluate pipelines.

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

Appendix: source

Thrown at src/edu/stanford/nlp/sentiment/SentimentCostAndGradient.java:540

      if (model.op.useTensors) {
        SimpleTensor tensor = model.getBinaryTensor(leftCategory, rightCategory);
        SimpleMatrix tensorIn = NeuralUtils.concatenate(leftVector, rightVector);
        SimpleMatrix tensorOut = tensor.bilinearProducts(tensorIn);
        nodeVector = NeuralUtils.elementwiseApplyTanh(W.mult(childrenVector).plus(tensorOut));
      } else {
        nodeVector = NeuralUtils.elementwiseApplyTanh(W.mult(childrenVector));
      }
    } else {
      StringBuilder error = new StringBuilder();
      error.append("SentimentCostAndGradient: Tree not correctly binarized:\n   ");
      error.append(tree);
      error.append("\nToo many top level constituents present: ");
      error.append("(" + tree.value());
      for (Tree child : tree.children()) {
        error.append(" (" + child.value() + " ...)");
      }
      error.append(")");
      throw new ForwardPropagationException(error.toString());
    }

    SimpleMatrix predictions = NeuralUtils.softmax(classification.mult(NeuralUtils.concatenateWithBias(nodeVector)));

    int index = getPredictedClass(predictions);
    if (!(tree.label() instanceof CoreLabel)) {
      log.info("SentimentCostAndGradient: warning: No CoreLabels in nodes: " + tree);
      throw new AssertionError("Expected CoreLabels in the nodes");
    }
    CoreLabel label = (CoreLabel) tree.label();
    label.set(RNNCoreAnnotations.Predictions.class, predictions);
    label.set(RNNCoreAnnotations.PredictedClass.class, index);
    label.set(RNNCoreAnnotations.NodeVector.class, nodeVector);
  } // end forwardPropagateTree

}

View on GitHub (pinned to 1b7edd19c4)