stanfordnlp/CoreNLP · error · IllegalArgumentException
Tree started with a label, not an Open! Offending proto
Error message
Tree started with a label, not an Open! Offending proto: ${proto} What it means
In fromProtoFlattenedTree, a value/label node encountered while the stack is empty means the sequence started with a label rather than an Open marker. Since labels only make sense attached to an open node, the serializer throws an IllegalArgumentException identifying the proto.
Solutions
- Produce flattened trees exclusively via toFlattenedTree so the sequence starts with Open.
- Validate that the first node hasOpenNode() before calling the deserializer.
- Catch IllegalArgumentException and re-obtain the parse from the annotator.
Example fix
// before
nodes = [label("S"), open(), ..., close()]; // label before any Open -> throws
// after
nodes = [open(), label("S"), ..., close()]; Defensive patterns
Strategy: validation
Validate before calling
if (proto.getNodesCount() == 0 || !proto.getNodes(0).hasOpenNode()) {
throw new IllegalArgumentException("flattened tree proto must begin with an Open node, not a label");
} Try / catch
try {
tree = ProtobufAnnotationSerializer.fromProto(proto);
} catch (IllegalArgumentException e) {
log.warn("Label encountered outside an open node: " + e.getMessage());
tree = null;
} Prevention
- Always emit open() before any label node
- Use the official toFlattenedTree writer
- Round-trip test trees in CI to catch writer regressions
When it happens
Trigger: Deserializing a FlattenedParseTree proto that begins with a value node, or that has a label node after all nodes have been closed — usually from protos built by hand or written by a non-conforming producer.
Common situations: Hand-rolled protobuf writers omitting the initial open marker; mixing node lists from different trees during transport or caching.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- Tree continued after it was already closed! Offending proto
- Tree added a child before a label was added to a node! …
- Tree started with a Close, not an Open! Offending proto
- Tree never finished! Offending proto
- Empty label not supported
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/41165351cc256e61.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java:2244
throw new IllegalArgumentException("Tree started with a Close, not an Open! Offending proto: " + proto);
}
LabeledScoredTreeNode child = stack.pop();
if (stack.size() == 0) {
// Popped off the last node. Guess we're done.
// We don't return yet so that we check that the
// iterator is finished first
finished = child;
} else {
LabeledScoredTreeNode parent = stack.peek();
// note: this is actually kind of slow if the tree is really wide,
// but hopefully that's not a common occurrence
// we could solve that by keeping a stack of list of children as well
parent.addChild(child);
}
} else {
if (stack.size() == 0) {
// demand that the tree always start with an Open
throw new IllegalArgumentException("Tree started with a label, not an Open! Offending proto: " + proto);
}
LabeledScoredTreeNode top = stack.peek();
if (top.label() == null) {
// the first label after an Open is the label
CoreLabel value = new CoreLabel();
value.setCategory(next.getValue());
value.setValue(next.getValue());
top.setLabel(value);
if (next.hasScore()) {
top.setScore(next.getScore());
}
} else {
// subsequence labels will be children
LabeledScoredTreeNode child = new LabeledScoredTreeNode();
CoreLabel value = new CoreLabel();
value.setCategory(next.getValue());
value.setValue(next.getValue());
child.setLabel(value);View on GitHub (pinned to 1b7edd19c4)