{"record":{"id":"fad3f6d6f715e797","repo":"hyperledger/fabric","slug":"error-marshaling-chaincodeproposalpayload-proto","errorCode":null,"errorMessage":"error marshaling ChaincodeProposalPayload: proto: Marshal called with nil","messagePattern":"error marshaling ChaincodeProposalPayload: proto: Marshal called with nil","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/proputils.go","lineNumber":137,"sourceCode":"\t\tChaincodeId: ccid,\n\t}\n\tcActBytes, err := proto.Marshal(cAct)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"error marshaling ChaincodeAction\")\n\t}\n\n\tprp := &peer.ProposalResponsePayload{\n\t\tExtension:    cActBytes,\n\t\tProposalHash: hash,\n\t}\n\tprpBytes, err := proto.Marshal(prp)\n\treturn prpBytes, errors.Wrap(err, \"error marshaling ProposalResponsePayload\")\n}\n\n// GetBytesChaincodeProposalPayload gets the chaincode proposal payload\nfunc GetBytesChaincodeProposalPayload(cpp *peer.ChaincodeProposalPayload) ([]byte, error) {\n\tif cpp == nil {\n\t\treturn nil, errors.New(\"error marshaling ChaincodeProposalPayload: proto: Marshal called with nil\")\n\t}\n\tcppBytes, err := proto.Marshal(cpp)\n\treturn cppBytes, errors.Wrap(err, \"error marshaling ChaincodeProposalPayload\")\n}\n\n// GetBytesResponse gets the bytes of Response\nfunc GetBytesResponse(res *peer.Response) ([]byte, error) {\n\tif res == nil {\n\t\treturn nil, errors.New(\"error marshaling Response: proto: Marshal called with nil\")\n\t}\n\tresBytes, err := proto.Marshal(res)\n\treturn resBytes, errors.Wrap(err, \"error marshaling Response\")\n}\n\n// GetBytesChaincodeEvent gets the bytes of ChaincodeEvent\nfunc GetBytesChaincodeEvent(event *peer.ChaincodeEvent) ([]byte, error) {\n\tif event == nil {\n\t\treturn nil, errors.New(\"error marshaling ChaincodeEvent: proto: Marshal called with nil\")","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/proputils.go#L119-L155","documentation":"GetBytesChaincodeProposalPayload explicitly returns this pre-computed error when called with a nil *peer.ChaincodeProposalPayload, mimicking proto.Marshal's nil error text. It is a guard added because marshaling nil would otherwise fail confusingly inside the library.","triggerScenarios":"Calling GetBytesChaincodeProposalPayload(nil), or via callers GetBytesProposalPayloadForTx / prepareTransaction when the upstream proposal payload was never constructed (e.g. proposal creation was skipped on error and its nil result was passed through).","commonSituations":"Ignoring the error from CreateChaincodeProposal and continuing with a nil payload; test harnesses assembling transactions without a proposal; SDK code paths where proposal generation silently failed.","solutions":["Check the error from proposal-creation functions before using the payload pointer","Ensure GetBytesProposalPayloadForTx receives a non-nil cpp built from a successful CreateChaincodeProposal call","Add a nil check at the call site before invoking GetBytesChaincodeProposalPayload"],"exampleFix":"// before\ncppBytes, err := protoutil.GetBytesChaincodeProposalPayload(proposal.Payload) // proposal is nil after earlier error ignored\n// after\nif proposal == nil || proposal.Payload == nil {\n    return errors.New(\"proposal or payload missing; check earlier proposal-creation error\")\n}\ncppBytes, err := protoutil.GetBytesChaincodeProposalPayload(proposal.Payload)","handlingStrategy":"type-guard","validationCode":"if proposal == nil || proposal.Payload == nil {\n\treturn errors.New(\"proposal/payload missing — check the error from CreateChaincodeProposal\")\n}\ncppBytes, err := protoutil.GetBytesChaincodeProposalPayload(proposal.Payload)","typeGuard":"func isProposalPayloadReady(proposal *peer.Proposal) bool {\n\treturn proposal != nil && proposal.Payload != nil\n}","tryCatchPattern":"cppBytes, err := protoutil.GetBytesChaincodeProposalPayload(cpp)\nif err != nil {\n\tif strings.Contains(err.Error(), \"Marshal called with nil\") {\n\t\treturn fmt.Errorf(\"proposal payload never created; upstream error swallowed: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Never ignore errors from CreateChaincodeProposal before using its result","Wrap multi-step tx building so any error aborts the whole flow","Use linters (errcheck) to catch swallowed errors"],"tags":["fabric","protobuf","nil-pointer","proposal-payload"],"backgroundTag":"nil-input-marshaling","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"}