{"record":{"id":"0de3ad985f9938d8","repo":"grpc-ecosystem/grpc-gateway","slug":"failed-to-unmarshal-code-generator-request-w","errorCode":null,"errorMessage":"failed to unmarshal code generator request: %w","messagePattern":"failed to unmarshal code generator request: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/codegenerator/parse_req.go","lineNumber":19,"sourceCode":"package codegenerator\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"google.golang.org/protobuf/types/pluginpb\"\n)\n\n// ParseRequest parses a code generator request from a proto Message.\nfunc ParseRequest(r io.Reader) (*pluginpb.CodeGeneratorRequest, error) {\n\tinput, err := io.ReadAll(r)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read code generator request: %w\", err)\n\t}\n\treq := new(pluginpb.CodeGeneratorRequest)\n\tif err := proto.Unmarshal(input, req); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal code generator request: %w\", err)\n\t}\n\treturn req, nil\n}\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/grpc-ecosystem/grpc-gateway/blob/a58a4436a376a4bcc7d8f10c4d4f919a8438bba9/internal/codegenerator/parse_req.go#L1-L23","documentation":"ParseRequest wraps proto.Unmarshal failures when the bytes read from the reader are not a valid CodeGeneratorRequest protobuf. The plugin received input that cannot be decoded as the expected pluginpb.CodeGeneratorRequest message.","triggerScenarios":"Running a protoc plugin binary directly with garbage/empty stdin; piping a text or truncated file instead of the serialized request; protoc/plugin version mismatch producing an undecodable payload; passing the wrong proto message type from a custom harness.","commonSituations":"Manual debugging of plugin binaries without a valid request.bin; writing plugin tests that pass hand-rolled bytes; older protoc generating requests incompatible with the plugin's protobuf runtime expectations.","solutions":["Ensure the input really is a serialized CodeGeneratorRequest — capture one via protoc and pipe that exact file","Regenerate/capture with matching protoc and google.golang.org/protobuf versions (go mod tidy; update protoc)","In tests, build a valid pluginpb.CodeGeneratorRequest and proto.Marshal it instead of using raw strings"],"exampleFix":"// before\nreq, err := codegenerator.ParseRequest(strings.NewReader(\"not protobuf\"))\n// after\ndata, _ := proto.Marshal(&pluginpb.CodeGeneratorRequest{})\nreq, err := codegenerator.ParseRequest(bytes.NewReader(data))","handlingStrategy":"try-catch","validationCode":"// sanity check before unmarshal in custom code\ninput, err := io.ReadAll(r)\nif err != nil || len(input) == 0 {\n    return fmt.Errorf(\"empty or unreadable plugin input\")\n}","typeGuard":null,"tryCatchPattern":"req, err := codegenerator.ParseRequest(r)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to unmarshal code generator request\") {\n        grpclog.Fatalf(\"input is not a CodeGeneratorRequest: %v\", err)\n    }\n    return err\n}","preventionTips":["Pipe only serialized CodeGeneratorRequest bytes into plugins; never text","Keep protoc and google.golang.org/protobuf versions compatible (go get -u google.golang.org/protobuf)","In tests, construct requests with proto.Marshal on a real pluginpb.CodeGeneratorRequest"],"tags":["go","protoc","plugin","protobuf","unmarshal"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"a58a4436a376a4bcc7d8f10c4d4f919a8438bba9","analyzedAt":"2026-09-02T10:28:31.537Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}