{"record":{"id":"811567e0411776a6","repo":"hyperledger/fabric","slug":"request-is-nil","errorCode":null,"errorMessage":"request is nil","messagePattern":"request is nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/cluster/commauth.go","lineNumber":300,"sourceCode":"\t}\n\n\tpayload.Signature = sig\n\tstepRequest := &orderer.ClusterNodeServiceStepRequest{\n\t\tPayload: &orderer.ClusterNodeServiceStepRequest_NodeAuthrequest{\n\t\t\tNodeAuthrequest: payload,\n\t\t},\n\t}\n\n\treturn cs.StepClient.Send(stepRequest)\n}\n\nfunc (cs *NodeClientStream) Context() context.Context {\n\treturn cs.StepClient.Context()\n}\n\nfunc BuildStepRequest(request *orderer.StepRequest) (*orderer.ClusterNodeServiceStepRequest, error) {\n\tif request == nil {\n\t\treturn nil, errors.New(\"request is nil\")\n\t}\n\tvar stepRequest *orderer.ClusterNodeServiceStepRequest\n\tif consReq := request.GetConsensusRequest(); consReq != nil {\n\t\tstepRequest = &orderer.ClusterNodeServiceStepRequest{\n\t\t\tPayload: &orderer.ClusterNodeServiceStepRequest_NodeConrequest{\n\t\t\t\tNodeConrequest: &orderer.NodeConsensusRequest{\n\t\t\t\t\tPayload:  consReq.Payload,\n\t\t\t\t\tMetadata: consReq.Metadata,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\treturn stepRequest, nil\n\t} else if subReq := request.GetSubmitRequest(); subReq != nil {\n\t\tstepRequest = &orderer.ClusterNodeServiceStepRequest{\n\t\t\tPayload: &orderer.ClusterNodeServiceStepRequest_NodeTranrequest{\n\t\t\t\tNodeTranrequest: &orderer.NodeTransactionOrderRequest{\n\t\t\t\t\tPayload:           subReq.Payload,\n\t\t\t\t\tLastValidationSeq: subReq.LastValidationSeq,","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/cluster/commauth.go#L282-L318","documentation":"BuildStepRequest converts an orderer.StepRequest (the etcdraft/consensus-facing message) into a ClusterNodeServiceStepRequest for the node-to-node service. It returns 'request is nil' when the incoming *orderer.StepRequest pointer is nil, as a defensive guard since there is no payload to convert.","triggerScenarios":"Calling Send() on a NodeClientStream with a nil *orderer.StepRequest, or calling BuildStepRequest(nil) directly.","commonSituations":"Upstream producer of StepRequest failed silently and returned nil without error; mismanaged pointer in a dispatch loop that forwards consensus/submit requests; tests passing nil fixtures.","solutions":["Fix the caller so it never invokes Send with a nil request; propagate errors from whatever produced the StepRequest instead of sending nil.","Add a nil check at the call site before calling Send and handle the failure there.","Log the origin of the nil request to find the producer returning nil."],"exampleFix":"// before\nerr := stream.Send(req) // req may be nil\n// after\nif req == nil {\n    return fmt.Errorf(\"cannot send nil step request\")\n}\nerr := stream.Send(req)","handlingStrategy":"type-guard","validationCode":"if request == nil {\n    return errors.New(\"refusing to send nil StepRequest\")\n}\nerr := stream.Send(request)","typeGuard":"func isValidStepRequest(r *orderer.StepRequest) bool {\n    return r != nil && r.GetPayload() != nil\n}","tryCatchPattern":"if err := stream.Send(req); err != nil {\n    if err.Error() == \"request is nil\" {\n        log.Errorf(\"nil step request from producer\")\n    }\n    return err\n}","preventionTips":["Never swallow errors from producers of StepRequest; a nil return must be surfaced.","Type-guard requests before handing them to Send.","Add lint/tests asserting Send is never called with nil in dispatch paths."],"tags":["fabric","nil-pointer","request-validation"],"backgroundTag":"nil-request-payload","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}