stanfordnlp/CoreNLP · error · FailedSerializationError

Protobuf dependency edge was null! Edge

Error message

Protobuf dependency edge was null!
Edge: ${edge}

What it means

Thrown by ProtobufAnnotationSerializer when a protobuf DependencyGraph edge has no 'dep' field set (the grammatical relation name), even though its endpoints resolve. Reconstructing the GrammaticalRelation requires the relation string, so the serializer aborts.

Solutions

  1. Set the dep field on every edge (e.g. setDep("nsubj")) before serializing.
  2. Reject/repair such edges upstream: skip edges lacking a dep or assign a default like 'dep'.
  3. Verify the producing code path always populates the relation, e.g. when converting a SemanticGraph to proto.

Example fix

// before
Edge.newBuilder().setSource(1).setTarget(2).build();
// after
Edge.newBuilder().setSource(1).setTarget(2).setDep("nsubj").build();
Defensive patterns

Strategy: validation

Validate before calling

boolean allEdgesHaveDep(CoreNLPProtos.DependencyGraph g) {
  return g.getEdgeList().stream().allMatch(CoreNLPProtos.DependencyGraph.Edge::hasDep);
}

Type guard

if (!ie.hasDep() || ie.getDep().isEmpty()) return null;

Try / catch

try {
  return serializer.fromProto(proto);
} catch (ProtobufAnnotationSerializer.FailedSerializationError e) {
  if (e.getMessage().contains("dependency edge was null")) {
    log.warn("Edge without relation label; skipping graph");
    return annotationWithoutGraph(proto);
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing a proto where Edge.hasDep() is false — i.e., the edge was built without calling setDep(), or the field was cleared.

Common situations: Custom pipeline tools that write dependency edges without relation labels, protobufs produced by older/other NLP tooling that omits relation names, or fields lost during proto manipulation.

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


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/b5d2157950239281. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java:2483

      nodes.put(in.getIndex(), in.getEmptyIndex(), in.getCopyAnnotation(), word);
      graph.addVertex(word);
      orderedNodes.add(word);
    }

    // add all edges to the actual graph
    for(CoreNLPProtos.DependencyGraph.Edge ie: proto.getEdgeList()){
      IndexedWord source = nodes.get(ie.getSource(), ie.getSourceEmpty(), ie.getSourceCopy());
      if (source == null) {
        throw new FailedSerializationError("Source of a dependency was null!\nEdge: " + ie);
      }
      IndexedWord target = nodes.get(ie.getTarget(), ie.getTargetEmpty(), ie.getTargetCopy());
      if (target == null) {
        throw new FailedSerializationError("Target of a dependency was null!\nEdge: " + ie);
      }
      synchronized (globalLock) {
        // this is not thread-safe: there are static fields in GrammaticalRelation
        if (!ie.hasDep()) {
          throw new FailedSerializationError("Protobuf dependency edge was null!\nEdge: " + ie);
        }
        GrammaticalRelation rel = GrammaticalRelation.valueOf(fromProto(ie.getLanguage()), ie.getDep());
        graph.addEdge(source, target, rel, 1.0, ie.hasIsExtra() && ie.getIsExtra());
      }
    }

    if (proto.getRootNodeCount() > 0) {
      Collection<IndexedWord> roots = proto.getRootNodeList().stream().map(idx -> orderedNodes.get(idx)).collect(Collectors.toList());
      graph.setRoots(roots);
    } else if (proto.getRootCount() > 0) {
      // assume empty nodes and copy nodes can't be the root
      // this is actually not true: there are examples in the UD Estonian EWT treebank
      // which have empty nodes as the root of the enhanced graph
      Collection<IndexedWord> roots = proto.getRootList().stream().map(rootI -> nodes.get(rootI, 0, 0)).collect(Collectors.toList());
      graph.setRoots(roots);
    } else {
      // Roots were not saved away
      // compute root nodes if non-empty

View on GitHub (pinned to 1b7edd19c4)