{"record":{"id":"a05d61902ee1c71e","repo":"hyperledger/fabric","slug":"failed-marshaling-request-to-bytes","errorCode":null,"errorMessage":"failed marshaling Request to bytes","messagePattern":"failed marshaling Request to bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"discovery/client/client.go","lineNumber":164,"sourceCode":"\treturn req\n}\n\nfunc (req *Request) addChaincodeQueryMapping(invocationChains []InvocationChain) {\n\treq.invocationChainMapping[req.lastIndex] = invocationChains\n}\n\nfunc (req *Request) addQueryMapping(queryType protoext.QueryType, key string) {\n\treq.queryMapping[queryType][key] = req.lastIndex\n\treq.lastIndex++\n}\n\n// Send sends the request and returns the response, or error on failure\nfunc (c *Client) Send(ctx context.Context, req *Request, auth *discovery.AuthInfo) (Response, error) {\n\treqToBeSent := proto.Clone(req.Request).(*discovery.Request)\n\treqToBeSent.Authentication = auth\n\tpayload, err := proto.Marshal(reqToBeSent)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed marshaling Request to bytes\")\n\t}\n\n\tsig, err := c.signRequest(payload)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed signing Request\")\n\t}\n\n\tconn, err := c.createConnection()\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed connecting to discovery service\")\n\t}\n\n\tcl := discovery.NewDiscoveryClient(conn)\n\tresp, err := cl.Discover(ctx, &discovery.SignedRequest{\n\t\tPayload:   payload,\n\t\tSignature: sig,\n\t})\n\tif err != nil {","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/discovery/client/client.go#L146-L182","documentation":"Client.Send in discovery/client/client.go:164 clones the Request, attaches the AuthInfo, and proto.Marshal's it before signing. If protobuf marshaling of the request fails, the underlying error is wrapped with 'failed marshaling Request to bytes'. This is rare because discovery Requests are well-formed protobuf messages, but happens if the request contains unmarshalable nested data.","triggerScenarios":"Calling Send with a Request built via NewRequest/AddQuery whose nested protobuf content cannot be marshaled (e.g. corrupted AuthInfo or invalid nested message bytes injected programmatically).","commonSituations":"Manually mutating a discovery.Request's fields with invalid values; embedding oversized or invalid byte fields; protobuf message corruption between versions of the discovery protobuf.","solutions":["Build the request only via discovery.NewRequest() and its Add* query methods; never hand-edit the inner proto message","Verify the discovery client and server use compatible protobuf definitions","Check the wrapped underlying error for the exact marshal failure","Recreate the Request object instead of reusing a mutated one"],"exampleFix":"// before: mutating the raw proto request\nreq.Request.Queries[0].ConfigQuery = &discovery.ConfigQuery{Channel: \"\"}\n\n// after: use the builder API\nreq := discovery.NewRequest()\nreq.AddConfigQuery(\"mychannel\")","handlingStrategy":"try-catch","validationCode":"// Build requests only via discovery.NewRequest() / Add* builders\nreq := discovery.NewRequest()\nreq.AddConfigQuery(channelID)","typeGuard":null,"tryCatchPattern":"resp, err := client.Send(ctx, req, auth)\nif err != nil {\n    var wrapped error\n    if strings.Contains(err.Error(), \"failed marshaling Request to bytes\") {\n        wrapped = fmt.Errorf(\"rebuild request via NewRequest: %w\", err)\n    }\n    _ = wrapped\n}","preventionTips":["Never mutate the inner proto Request directly","Keep discovery protobuf versions in sync between client and peer","Recreate Request objects rather than reusing mutated ones"],"tags":["hyperledger-fabric","discovery-client","protobuf","marshaling"],"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"}