{"record":{"id":"49f3f2e7682987f6","repo":"micro/go-micro","slug":"failed-to-marshal-v-is-not-type-of-byte","errorCode":null,"errorMessage":"failed to marshal: %v is not type of *[]byte","messagePattern":"failed to marshal: (.+?) is not type of \\*\\[\\]byte","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/grpc/codec.go","lineNumber":98,"sourceCode":"\tswitch m := v.(type) {\n\tcase proto.Message:\n\t\treturn proto.Unmarshal(data, m)\n\tcase protoiface.MessageV1:\n\t\t// #2333 compatible with etcd legacy proto.Message\n\t\tm2 := protoimpl.X.ProtoMessageV2Of(m)\n\t\treturn proto.Unmarshal(data, m2)\n\t}\n\treturn fmt.Errorf(\"failed to unmarshal: %v is not type of proto.Message\", v)\n}\n\nfunc (protoCodec) Name() string {\n\treturn \"proto\"\n}\n\nfunc (bytesCodec) Marshal(v interface{}) ([]byte, error) {\n\tb, ok := v.(*[]byte)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"failed to marshal: %v is not type of *[]byte\", v)\n\t}\n\treturn *b, nil\n}\n\nfunc (bytesCodec) Unmarshal(data []byte, v interface{}) error {\n\tb, ok := v.(*[]byte)\n\tif !ok {\n\t\treturn fmt.Errorf(\"failed to unmarshal: %v is not type of *[]byte\", v)\n\t}\n\t*b = data\n\treturn nil\n}\n\nfunc (bytesCodec) Name() string {\n\treturn \"bytes\"\n}\n\nfunc (jsonCodec) Marshal(v interface{}) ([]byte, error) {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/client/grpc/codec.go#L80-L116","documentation":"The bytes codec Marshal only accepts a *[]byte; the value handed to it was any other type. This codec is a raw passthrough — it forwards your byte slice verbatim as the gRPC message body — so it cannot serialize structured values.","triggerScenarios":"Using Content-Type application/grpc+bytes (or registering bytesCodec) and calling Publish/Call with a struct, string (not *[]byte), or map instead of a pointer to a byte slice.","commonSituations":"Selecting the bytes codec for efficiency but forgetting to pre-marshal payloads; passing a []byte (non-pointer) which also fails the *[]byte assertion; switching codecs without updating call sites.","solutions":["Wrap the payload: pre-marshal to bytes and pass &payload","Switch Content-Type to application/grpc+proto or +json for structured types","Pass *raw.Frame if you intend raw framing","Audit Publish/Call sites after any codec configuration change"],"exampleFix":"// before\nclient.Publish(ctx, topic, map[string]string{\"k\": \"v\"})\n// after\nb, _ := json.Marshal(map[string]string{\"k\": \"v\"})\nclient.Publish(ctx, topic, &b)","handlingStrategy":"type-guard","validationCode":"if _, ok := payload.(*[]byte); !ok {\n    return fmt.Errorf(\"bytes codec requires *[]byte, got %T\", payload)\n}","typeGuard":"func isBytePtr(v interface{}) bool {\n    _, ok := v.(*[]byte)\n    return ok\n}","tryCatchPattern":"if err := client.Publish(ctx, topic, payload); err != nil {\n    if strings.Contains(err.Error(), \"is not type of *[]byte\") {\n        // marshal payload to bytes and pass a pointer\n    }\n}","preventionTips":["Pre-marshal structured data before publishing with the bytes codec","Remember it must be *[]byte, not []byte","Consider application/grpc+json if you want automatic marshaling","Add codec round-trip unit tests"],"tags":["grpc","codec","bytes","serialization"],"backgroundTag":"grpc-codec-type-mismatch","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}