{"record":{"id":"8e53cfab2ecf512e","repo":"stanfordnlp/CoreNLP","slug":"tree-never-finished-offending-proto-proto","errorCode":null,"errorMessage":"Tree never finished!  Offending proto: ${proto}","messagePattern":"Tree never finished!  Offending proto: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java","lineNumber":2271,"sourceCode":"          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);\n          top.addChild(child);\n          if (next.hasScore()) {\n            child.setScore(next.getScore());\n          }\n        }\n      }\n    }\n    if (finished == null) {\n      throw new IllegalArgumentException(\"Tree never finished!  Offending proto: \" + proto);\n    }\n    return finished;\n  }\n\n  /**\n   * Retrieve a Tree object and then attach the tokens passed in.\n   *\n   * Useful for keeping the tokens in the tree synchronized with the tokens in a sentence.\n   */\n  public static Tree fromProto(CoreNLPProtos.ParseTree proto, List<CoreLabel> tokens) {\n    Tree tree = fromProto(proto);\n    Trees.setLeafLabels(tree, tokens);\n    return tree;\n  }\n\n  /**\n   * Retrieve a Tree object from a saved protobuf.\n   * This is not intended to be used on its own, but it is safe (lossless) to do so and therefore it is","sourceCodeStart":2253,"sourceCodeEnd":2289,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java#L2253-L2289","documentation":"After consuming all nodes of a FlattenedParseTree proto, fromProtoFlattenedTree checks that a completed root tree ('finished') exists. If the nodes list ended with unclosed Open nodes, the tree was never completed, so an IllegalArgumentException naming the proto is thrown.","triggerScenarios":"Deserializing a FlattenedParseTree proto whose nodes list has more Open markers than Close markers — e.g. truncated protos, or builders that forgot the final root closeNode.","commonSituations":"Network truncation or partial writes of serialized annotations; custom serializers that never emit the last Close for the root.","solutions":["Regenerate the proto with toFlattenedTree, which balances every Open with a Close.","Check Open/Close balance (count equality and non-empty stack at end) before deserializing.","Catch IllegalArgumentException, log the corrupt annotation, and re-parse the sentence."],"exampleFix":"// before\nnodes = [open(), label(\"ROOT\"), open(), label(\"NP\"), close()]; // NP closed but ROOT never closed\n// after\nnodes = [open(), label(\"ROOT\"), open(), label(\"NP\"), close(), close()];","handlingStrategy":"validation","validationCode":"int depth = 0;\nfor (var n : proto.getNodesList()) {\n  if (n.hasOpenNode()) depth++;\n  else if (n.hasCloseNode()) depth--;\n}\nif (depth != 0) throw new IllegalArgumentException(\"unbalanced Open/Close nodes (ends at depth \" + depth + \")\");","typeGuard":null,"tryCatchPattern":"try {\n  tree = ProtobufAnnotationSerializer.fromProto(proto);\n} catch (IllegalArgumentException e) {\n  log.warn(\"Tree never finished (truncated proto?): \" + e.getMessage());\n  tree = null;\n}","preventionTips":["Verify balanced Open/Close counts before deserializing","Length-prefix and checksum protos in transit to detect truncation","Ensure the final Close for the root is always emitted by custom writers"],"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"}