{"record":{"id":"dde52889ee06e325","repo":"hyperledger/fabric","slug":"received-nil-proposal-response-dde528","errorCode":null,"errorMessage":"received nil proposal response","messagePattern":"received nil proposal response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/lifecycle/chaincode/commit.go","lineNumber":192,"sourceCode":"\tfor _, endorser := range c.EndorserClients {\n\t\tproposalResponse, err := endorser.ProcessProposal(context.Background(), signedProposal)\n\t\tif err != nil {\n\t\t\treturn errors.WithMessage(err, \"failed to endorse proposal\")\n\t\t}\n\t\tresponses = append(responses, proposalResponse)\n\t}\n\n\tif len(responses) == 0 {\n\t\t// this should only be empty due to a programming bug\n\t\treturn errors.New(\"no proposal responses received\")\n\t}\n\n\t// all responses will be checked when the signed transaction is created.\n\t// for now, just set this so we check the first response's status\n\tproposalResponse := responses[0]\n\n\tif proposalResponse == nil {\n\t\treturn errors.New(\"received nil proposal response\")\n\t}\n\n\tif proposalResponse.Response == nil {\n\t\treturn errors.New(\"received proposal response with nil response\")\n\t}\n\n\tif proposalResponse.Response.Status != int32(cb.Status_SUCCESS) {\n\t\treturn errors.Errorf(\"proposal failed with status: %d - %s\", proposalResponse.Response.Status, proposalResponse.Response.Message)\n\t}\n\t// assemble a signed transaction (it's an Envelope message)\n\tenv, err := protoutil.CreateSignedTx(proposal, c.Signer, responses...)\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"failed to create signed transaction\")\n\t}\n\n\tvar dg *chaincode.DeliverGroup\n\tvar ctx context.Context\n\tif c.Input.WaitForEvent {","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/lifecycle/chaincode/commit.go#L174-L210","documentation":"Commit picks responses[0] as the representative proposal response and checks it before creating the signed transaction. If that first element is a nil pointer, the code throws this error to avoid a nil dereference.","triggerScenarios":"The collected responses slice contains a nil *pb.ProposalResponse at index 0 — again indicative of a programming bug in the collection code rather than a normal runtime condition.","commonSituations":"Custom tooling appending unvalidated endorser results (including nils on endorse failure); test fixtures with nil entries; patched fabric code paths.","solutions":["Skip nil proposal responses when building the responses slice, or fail early in the caller.","Ensure endorse errors are handled instead of silently appending nil results.","Validate each endorser client's response before Commit.","If stock CLI produces this, capture logs and report a bug."],"exampleFix":"// before\nresponses = append(responses, proposalResponse)\n// after\nif proposalResponse == nil { return errors.New(\"endorser returned nil response\") }\nresponses = append(responses, proposalResponse)","handlingStrategy":"type-guard","validationCode":"for _, resp := range endorserResponses {\n    if resp == nil { return errors.New(\"endorser returned nil response\") }\n}\n","typeGuard":"func isNonNilResponse(r *pb.ProposalResponse) bool { return r != nil }","tryCatchPattern":"if err := commit(...); err != nil {\n    if strings.Contains(err.Error(), \"received nil proposal response\") {\n        // sanitize collected responses before calling Commit\n    }\n}","preventionTips":["Filter nil entries out of the responses slice before Commit.","Handle endorse() errors instead of appending failed (nil) results.","Avoid mock endorsers that return nil without mirroring real errors."],"tags":["hyperledger-fabric","nil-check","proposal-response","programming-bug"],"backgroundTag":"nil-proposal-response","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"}