{"record":{"id":"b610fd54dd4947cf","repo":"dgraph-io/dgraph","slug":"updateextsnapshotstreamingstaterequest-cannot-have-b610fd","errorCode":null,"errorMessage":"UpdateExtSnapshotStreamingStateRequest cannot have both Start and Finish set to true","messagePattern":"UpdateExtSnapshotStreamingStateRequest cannot have both Start and Finish set to true","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/import.go","lineNumber":463,"sourceCode":"\t\t}\n\t\tif _, err := out.Recv(); err != nil {\n\t\t\treturn fmt.Errorf(\"ack data downstream(%d): %w\", groupId, err)\n\t\t}\n\t\tif err := in.Send(&api.StreamExtSnapshotResponse{}); err != nil {\n\t\t\treturn fmt.Errorf(\"send ack upstream: %w\", err)\n\t\t}\n\n\t}\n}\n\nfunc (w *grpcWorker) UpdateExtSnapshotStreamingState(ctx context.Context,\n\treq *api.UpdateExtSnapshotStreamingStateRequest) (*pb.Status, error) {\n\tif req == nil {\n\t\treturn nil, errors.New(\"UpdateExtSnapshotStreamingStateRequest must not be nil\")\n\t}\n\n\tif req.Start && req.Finish {\n\t\treturn nil, errors.New(\"UpdateExtSnapshotStreamingStateRequest cannot have both Start and Finish set to true\")\n\t}\n\n\tglog.Infof(\"[import] Applying import mode proposal: %+v\", req)\n\terr := groups().Node.proposeAndWait(ctx, &pb.Proposal{ExtSnapshotState: req})\n\n\treturn &pb.Status{}, err\n}\n\n// StreamExtSnapshot handles the stream of key-value pairs sent from proxy alpha.\n// It receives a Forward flag from the stream to determine if the current node is the leader.\n// If the node is the leader (Forward is true), it streams the data to its followers.\n// Otherwise, it simply writes the data to BadgerDB and flushes it.\nfunc (w *grpcWorker) StreamExtSnapshot(stream pb.Worker_StreamExtSnapshotServer) error {\n\tglog.Info(\"[import] trying to update the import mode to false\")\n\tdefer x.ExtSnapshotStreamingState(false)\n\n\t// Receive the first message to check the Forward flag.\n\t// If Forward is true, this node is the leader and should forward the stream to its followers.","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/import.go#L445-L481","documentation":"The Start and Finish flags of UpdateExtSnapshotStreamingStateRequest are mutually exclusive: Start turns import/streaming mode on, Finish turns it off. Setting both is ambiguous and rejected with this error before any Raft proposal is made.","triggerScenarios":"Sending an UpdateExtSnapshotStreamingStateRequest with both Start=true and Finish=true via the gRPC API, e.g. reusing a populated struct and only flipping one flag.","commonSituations":"Copy/reuse of a previous request struct without resetting fields; buggy client code computing flags; a mistaken attempt to 'restart' streaming in one call.","solutions":["Send two separate calls: one with Start=true, later one with Finish=true.","Reset the struct before reuse: &api.UpdateExtSnapshotStreamingStateRequest{Start: true}.","Validate flags client-side before invoking the RPC."],"exampleFix":"// before\nreq := &api.UpdateExtSnapshotStreamingStateRequest{Start: prev.Finish}\nreq.Start, req.Finish = true, true\n// after\nreq := &api.UpdateExtSnapshotStreamingStateRequest{Finish: true}","handlingStrategy":"validation","validationCode":"if req != nil && req.Start && req.Finish {\n    return errors.New(\"Start and Finish are mutually exclusive; send two separate requests\")\n}","typeGuard":"func isAmbiguousStateReq(req *api.UpdateExtSnapshotStreamingStateRequest) bool {\n    return req != nil && req.Start && req.Finish\n}","tryCatchPattern":"if _, err := wc.UpdateExtSnapshotStreamingState(ctx, req); err != nil {\n    if strings.Contains(err.Error(), \"both Start and Finish\") { /* send separate Start and Finish calls */ }\n}","preventionTips":["Send Start and Finish as two separate RPC calls","Reset reused request structs field-by-field instead of mutating old ones","Validate mutually exclusive flags client-side before RPCs"],"tags":["validation","grpc","conflicting-flags"],"backgroundTag":"conflicting-request-flags","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}