{"record":{"id":"e94f404d8a52d792","repo":"hyperledger/fabric","slug":"error-marshaling-proposal","errorCode":null,"errorMessage":"error marshaling proposal","messagePattern":"error marshaling proposal","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/lifecycle/chaincode/common.go","lineNumber":59,"sourceCode":"\n// Writer defines the interface needed for writing a file\ntype Writer interface {\n\tWriteFile(string, string, []byte) error\n}\n\nfunc signProposal(proposal *pb.Proposal, signer Signer) (*pb.SignedProposal, error) {\n\t// check for nil argument\n\tif proposal == nil {\n\t\treturn nil, errors.New(\"proposal cannot be nil\")\n\t}\n\n\tif signer == nil {\n\t\treturn nil, errors.New(\"signer cannot be nil\")\n\t}\n\n\tproposalBytes, err := proto.Marshal(proposal)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"error marshaling proposal\")\n\t}\n\n\tsignature, err := signer.Sign(proposalBytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &pb.SignedProposal{\n\t\tProposalBytes: proposalBytes,\n\t\tSignature:     signature,\n\t}, nil\n}\n\nfunc createPolicyBytes(signaturePolicy, channelConfigPolicy string) ([]byte, error) {\n\tif signaturePolicy == \"\" && channelConfigPolicy == \"\" {\n\t\t// no policy, no problem\n\t\treturn nil, nil\n\t}","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/lifecycle/chaincode/common.go#L41-L77","documentation":"After the proposal is signed, the bytes must be serialized with proto.Marshal. If protobuf marshaling of the *pb.Proposal fails, the error is wrapped as \"error marshaling proposal\". This signals the proposal message is corrupt or violates protobuf invariants (e.g. invalid oneof state, unsupported field).","triggerScenarios":"signProposal calls proto.Marshal(proposal) and receives a non-nil error — typically from a hand-crafted or corrupted pb.Proposal rather than one built by the CLI.","commonSituations":"Custom clients constructing proposals with invalid fields; protobuf version mismatch in vendored builds; fuzz/edge tests injecting malformed messages.","solutions":["Inspect the wrapped underlying error to identify which field fails marshaling","Rebuild the proposal via the standard createInput/createCommand path instead of hand-crafting it","Align protobuf/fabric dependency versions in go.mod"],"exampleFix":"// before\nsp, err := signProposal(customProposal, signer) // corrupt proposal\n// after\nproposal, err := createInput(...).buildProposal() // canonical construction\nif err != nil {\n    return err\n}\nsp, err := signProposal(proposal, signer)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"sp, err := signProposal(proposal, signer)\nif err != nil {\n    if strings.Contains(err.Error(), \"error marshaling proposal\") {\n        return fmt.Errorf(\"proposal bytes invalid: %w\", errors.Unwrap(err))\n    }\n    return err\n}","preventionTips":["Construct proposals through standard library helpers, not by hand","Keep fabric and google.golang.org/protobuf versions aligned in go.mod","Validate hand-crafted proposals with proto.Marshal in tests"],"tags":["fabric","protobuf","serialization"],"backgroundTag":"protobuf-marshal-failed","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"}