stanfordnlp/CoreNLP · error · FailedSerializationError

Target of a dependency was null! Edge

Error message

Target of a dependency was null!
Edge: ${edge}

What it means

Thrown by ProtobufAnnotationSerializer when a DependencyGraph edge's target node (by index, empty-flag, copy-flag triple) cannot be found in the node map built from the proto message. This indicates a corrupt or incompletely populated serialized dependency graph, so deserialization fails with FailedSerializationError.

Solutions

  1. Reserialize the annotation with a matching CoreNLP version so node/edge indexes agree.
  2. Add the missing target node to the proto's node list with the exact nodeIndex/nodeEmpty/nodeCopy the edge references.
  3. Log and inspect the offending Edge printed in the error to identify the dangling node reference.

Example fix

// before: edge points at target 7 with no such node
Edge.newBuilder().setSource(1).setTarget(7).build();
// after: emit the target node too
graph.addNodesBuilder().setNodeIndex(7).setWord("cat");
graph.addEdgesBuilder().setSource(1).setTarget(7).setDep("obj");
Defensive patterns

Strategy: validation

Validate before calling

boolean allEdgeTargetsPresent(CoreNLPProtos.DependencyGraph g) {
  Set<Integer> idx = g.getNodeList().stream().map(CoreNLPProtos.Node::getNodeIndex).collect(Collectors.toSet());
  return g.getEdgeList().stream().allMatch(e -> idx.contains(e.getTarget()));
}

Type guard

if (nodes.get(ie.getTarget(), ie.getTargetEmpty(), ie.getTargetCopy()) == null) return null;

Try / catch

try {
  return serializer.fromProto(proto);
} catch (ProtobufAnnotationSerializer.FailedSerializationError e) {
  if (e.getMessage().startsWith("Target of a dependency was null")) {
    return fallbackDeserializeIgnoringGraph(proto);
  }
  throw e;
}

Prevention

When it happens

Trigger: Deserializing a CoreNLPProtos message where DependencyGraph.Edge.getTarget() refers to a node absent from the proto's node list (mismatched nodeIndex/nodeEmpty/nodeCopy).

Common situations: Protobufs generated by incompatible CoreNLP versions, partially written/truncated serialized pipelines, or hand-crafted protos missing node entries.

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

Appendix: source

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

      }
      if (word.index() < 0 && in.getIndex() >= 0) {
        word.setIndex(in.getIndex());
      }

      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

View on GitHub (pinned to 1b7edd19c4)