{"record":{"id":"f31e72ed0c9c2ea7","repo":"stanfordnlp/CoreNLP","slug":"source-of-a-dependency-was-null-edge-edge","errorCode":null,"errorMessage":"Source of a dependency was null!\nEdge: ${edge}","messagePattern":"Source of a dependency was null!\nEdge: (.+?)","errorType":"exception","errorClass":"FailedSerializationError","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java","lineNumber":2474,"sourceCode":"        word.setDocID(docid);\n      }\n      if (word.sentIndex() < 0 && in.getSentenceIndex() >= 0) {\n        word.setSentIndex(in.getSentenceIndex());\n      }\n      if (word.index() < 0 && in.getIndex() >= 0) {\n        word.setIndex(in.getIndex());\n      }\n\n      nodes.put(in.getIndex(), in.getEmptyIndex(), in.getCopyAnnotation(), word);\n      graph.addVertex(word);\n      orderedNodes.add(word);\n    }\n\n    // add all edges to the actual graph\n    for(CoreNLPProtos.DependencyGraph.Edge ie: proto.getEdgeList()){\n      IndexedWord source = nodes.get(ie.getSource(), ie.getSourceEmpty(), ie.getSourceCopy());\n      if (source == null) {\n        throw new FailedSerializationError(\"Source of a dependency was null!\\nEdge: \" + ie);\n      }\n      IndexedWord target = nodes.get(ie.getTarget(), ie.getTargetEmpty(), ie.getTargetCopy());\n      if (target == null) {\n        throw new FailedSerializationError(\"Target of a dependency was null!\\nEdge: \" + ie);\n      }\n      synchronized (globalLock) {\n        // this is not thread-safe: there are static fields in GrammaticalRelation\n        if (!ie.hasDep()) {\n          throw new FailedSerializationError(\"Protobuf dependency edge was null!\\nEdge: \" + ie);\n        }\n        GrammaticalRelation rel = GrammaticalRelation.valueOf(fromProto(ie.getLanguage()), ie.getDep());\n        graph.addEdge(source, target, rel, 1.0, ie.hasIsExtra() && ie.getIsExtra());\n      }\n    }\n\n    if (proto.getRootNodeCount() > 0) {\n      Collection<IndexedWord> roots = proto.getRootNodeList().stream().map(idx -> orderedNodes.get(idx)).collect(Collectors.toList());\n      graph.setRoots(roots);","sourceCodeStart":2456,"sourceCodeEnd":2492,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/pipeline/ProtobufAnnotationSerializer.java#L2456-L2492","documentation":"Thrown by ProtobufAnnotationSerializer when deserializing a protobuf DependencyGraph: an edge references a source node (by index, empty-flag, and copy-flag) that is not present in the node map built from the proto. The serializer treats this as an unfixable inconsistency in the serialized annotation and aborts via FailedSerializationError.","triggerScenarios":"Calling ProtobufAnnotationSerializer.fromProto / readAnnotation on a CoreNLPProtos message whose DependencyGraph.Edge.getSource() points to a node index/empty/copy triple never added via the edge list's node entries.","commonSituations":"Hand-constructed or truncated protobuf messages, messages written by a different CoreNLP version with a mismatched node indexing scheme, or third-party tools generating dependency protos without emitting all nodes.","solutions":["Regenerate the protobuf annotation with the same CoreNLP version that will deserialize it.","Inspect the failing Edge (printed in the message) and add the missing source node to the proto's node list before deserializing.","If building protos manually, ensure every edge endpoint is also present in DependencyGraph.node with matching nodeIndex/nodeEmpty/nodeCopy values."],"exampleFix":"// before: manually built edge referencing node index 5 that was never added\nEdge.newBuilder().setSource(5).setTarget(2).build();\n// after: add the node first\ngraph.addNodesBuilder().setNodeIndex(5).setWord(\"dog\");\ngraph.addEdgesBuilder().setSource(5).setTarget(2).setDep(\"nsubj\");","handlingStrategy":"validation","validationCode":"boolean edgeNodesPresent(CoreNLPProtos.DependencyGraph g) {\n  Set<Long> keys = new HashSet<>();\n  for (var n : g.getNodeList()) keys.add(nodeKey(n));\n  return g.getEdgeList().stream().allMatch(e -> keys.contains((long) e.getSource()));\n}","typeGuard":"if (nodes.get(ie.getSource(), ie.getSourceEmpty(), ie.getSourceCopy()) == null) return null;","tryCatchPattern":"try {\n  Annotation ann = serializer.fromProto(proto);\n} catch (ProtobufAnnotationSerializer.FailedSerializationError e) {\n  log.error(\"Corrupt dependency graph proto: \" + e.getMessage());\n  throw new IllegalArgumentException(\"Malformed serialized annotation\", e);\n}","preventionTips":["Serialize and deserialize with the same CoreNLP version.","Never hand-edit DependencyGraph protos without updating both node and edge lists.","Round-trip test: deserialize a serialized pipeline output in CI."],"tags":["protobuf","serialization","dependency-graph","corenlp"],"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-17T15:17:12.973Z"}