{"record":{"id":"41165351cc256e61","repo":"stanfordnlp/CoreNLP","slug":"tree-started-with-a-label-not-an-open-offending","errorCode":null,"errorMessage":"Tree started with a label, not an Open!  Offending proto: ${proto}","messagePattern":"Tree started with a label, not an Open!  Offending proto: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java","lineNumber":2244,"sourceCode":"          throw new IllegalArgumentException(\"Tree started with a Close, not an Open!  Offending proto: \" + proto);\n        }\n        LabeledScoredTreeNode child = stack.pop();\n        if (stack.size() == 0) {\n          // Popped off the last node.  Guess we're done.\n          // We don't return yet so that we check that the\n          // iterator is finished first\n          finished = child;\n        } else {\n          LabeledScoredTreeNode parent = stack.peek();\n          // note: this is actually kind of slow if the tree is really wide,\n          // but hopefully that's not a common occurrence\n          // we could solve that by keeping a stack of list of children as well\n          parent.addChild(child);\n        }\n      } else {\n        if (stack.size() == 0) {\n          // demand that the tree always start with an Open\n          throw new IllegalArgumentException(\"Tree started with a label, not an Open!  Offending proto: \" + proto);\n        }\n        LabeledScoredTreeNode top = stack.peek();\n        if (top.label() == null) {\n          // the first label after an Open is the label\n          CoreLabel value = new CoreLabel();\n          value.setCategory(next.getValue());\n          value.setValue(next.getValue());\n          top.setLabel(value);\n          if (next.hasScore()) {\n            top.setScore(next.getScore());\n          }\n        } else {\n          // subsequence labels will be children\n          LabeledScoredTreeNode child = new LabeledScoredTreeNode();\n          CoreLabel value = new CoreLabel();\n          value.setCategory(next.getValue());\n          value.setValue(next.getValue());\n          child.setLabel(value);","sourceCodeStart":2226,"sourceCodeEnd":2262,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java#L2226-L2262","documentation":"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.","triggerScenarios":"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.","commonSituations":"Hand-rolled protobuf writers omitting the initial open marker; mixing node lists from different trees during transport or caching.","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."],"exampleFix":"// before\nnodes = [label(\"S\"), open(), ..., close()]; // label before any Open -> throws\n// after\nnodes = [open(), label(\"S\"), ..., close()];","handlingStrategy":"validation","validationCode":"if (proto.getNodesCount() == 0 || !proto.getNodes(0).hasOpenNode()) {\n  throw new IllegalArgumentException(\"flattened tree proto must begin with an Open node, not a label\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  tree = ProtobufAnnotationSerializer.fromProto(proto);\n} catch (IllegalArgumentException e) {\n  log.warn(\"Label encountered outside an open node: \" + e.getMessage());\n  tree = null;\n}","preventionTips":["Always emit open() before any label node","Use the official toFlattenedTree writer","Round-trip test trees in CI to catch writer regressions"],"tags":["serialization","protobuf","tree","malformed-input"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}