dgraph-io/dgraph · error
UpdateExtSnapshotStreamingStateRequest must not be nil
Error message
UpdateExtSnapshotStreamingStateRequest must not be nil
What it means
UpdateExtSnapshotStreamingState validates its request before proposing it to the Raft group. A nil *api.UpdateExtSnapshotStreamingStateRequest is rejected outright with this error because there is no state change to apply.
Source
Thrown at worker/import.go:459
// Normal data chunk: send -> wait ack -> send upstream ack.
if err := out.Send(&api.StreamExtSnapshotRequest{Pkt: req.Pkt}); err != nil {
return fmt.Errorf("send data downstream(%d): %w", groupId, err)
}
if _, err := out.Recv(); err != nil {
return fmt.Errorf("ack data downstream(%d): %w", groupId, err)
}
if err := in.Send(&api.StreamExtSnapshotResponse{}); err != nil {
return fmt.Errorf("send ack upstream: %w", err)
}
}
}
func (w *grpcWorker) UpdateExtSnapshotStreamingState(ctx context.Context,
req *api.UpdateExtSnapshotStreamingStateRequest) (*pb.Status, error) {
if req == nil {
return nil, errors.New("UpdateExtSnapshotStreamingStateRequest must not be nil")
}
if req.Start && req.Finish {
return nil, errors.New("UpdateExtSnapshotStreamingStateRequest cannot have both Start and Finish set to true")
}
glog.Infof("[import] Applying import mode proposal: %+v", req)
err := groups().Node.proposeAndWait(ctx, &pb.Proposal{ExtSnapshotState: req})
return &pb.Status{}, err
}
// StreamExtSnapshot handles the stream of key-value pairs sent from proxy alpha.
// It receives a Forward flag from the stream to determine if the current node is the leader.
// If the node is the leader (Forward is true), it streams the data to its followers.
// Otherwise, it simply writes the data to BadgerDB and flushes it.
func (w *grpcWorker) StreamExtSnapshot(stream pb.Worker_StreamExtSnapshotServer) error {
glog.Info("[import] trying to update the import mode to false")View on GitHub (pinned to 759e242be6)
Solutions
- Always pass a non-nil &api.UpdateExtSnapshotStreamingStateRequest{} with Start or Finish set.
- Check the caller that builds the request and initialize it.
- If using a generic client wrapper, ensure it does not drop an empty-but-intended message.
Example fix
// before
resp, err := wc.UpdateExtSnapshotStreamingState(ctx, nil)
// after
req := &api.UpdateExtSnapshotStreamingStateRequest{Start: true}
resp, err := wc.UpdateExtSnapshotStreamingState(ctx, req) Defensive patterns
Strategy: validation
Validate before calling
if req == nil {
return errors.New("UpdateExtSnapshotStreamingStateRequest must be initialized before calling")
} Type guard
func validStateReq(req *api.UpdateExtSnapshotStreamingStateRequest) bool {
return req != nil
} Try / catch
if _, err := wc.UpdateExtSnapshotStreamingState(ctx, req); err != nil {
if strings.Contains(err.Error(), "must not be nil") { /* fix caller: build request */ }
} Prevention
- Always construct the request struct explicitly before the RPC
- Never pass nil protobuf messages to worker RPCs
- Add client-side nil checks in wrapper/SDK functions
When it happens
Trigger: Calling the gRPC Worker.UpdateExtSnapshotStreamingState API (directly or via a client) with a nil request message, e.g. constructing the call programmatically without instantiating the request struct.
Common situations: Hand-written gRPC client code passing nil; a wrapper/SDK forwarding an unset message; tests invoking the worker method directly with nil.
Related errors
- connection string cannot be empty
- Tablets are empty in %+v
- Group ID is Zero in %+v
- Tablet predicate is empty in %+v
- UpdateExtSnapshotStreamingStateRequest must not be nil
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/5ef7c29df28a4aa0.
Report an issue: GitHub.