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
- Reserialize the annotation with a matching CoreNLP version so node/edge indexes agree.
- Add the missing target node to the proto's node list with the exact nodeIndex/nodeEmpty/nodeCopy the edge references.
- 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
- Validate node/edge referential integrity before deserializing third-party protos.
- Keep producer and consumer CoreNLP versions in sync.
- Checksum or re-serialize large annotation archives to detect truncation.
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
- Protobuf dependency edge was null! Edge
- Source of a dependency was null! Edge
- ERROR: Invalid dependency node line
- ERROR: Invalid format for dependency graph
- Keys are not being serialized
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 graphView on GitHub (pinned to 1b7edd19c4)