{"record":{"id":"629db775e6d2c067","repo":"micro/go-micro","slug":"failed-to-unmarshal-v-is-not-type-of-byte","errorCode":null,"errorMessage":"failed to unmarshal: %v is not type of *[]byte","messagePattern":"failed to unmarshal: (.+?) is not type of \\*\\[\\]byte","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/grpc/codec.go","lineNumber":106,"sourceCode":"\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) {\n\tif b, ok := v.(*bytes.Frame); ok {\n\t\treturn b.Data, nil\n\t}\n\n\tif pb, ok := v.(proto.Message); ok {\n\t\tbytes, err := protojson.Marshal(pb)\n\t\tif err != nil {\n\t\t\treturn nil, err","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/client/grpc/codec.go#L88-L124","documentation":"The bytes codec Unmarshal was given a destination that is not a *[]byte. Since this codec copies the raw response bytes into the target, only a pointer to a byte slice can receive them.","triggerScenarios":"Subscribing or calling with the bytes codec (application/grpc+bytes) but providing a struct/map pointer (or a non-pointer []byte) as the message destination.","commonSituations":"Mixed codecs across client/server — server sends bytes, subscriber decodes into a struct; refactored code changed the response type but kept the bytes Content-Type.","solutions":["Provide a *[]byte as the message target and decode it yourself","Align client and server Content-Types (e.g. both application/grpc+json)","Use *raw.Frame consistently for raw transports","Add a codec test in CI that round-trips a message to catch mismatches"],"exampleFix":"// before\nvar resp MyStruct\nclient.Call(ctx, req, &resp)\n// after\nvar rawBytes []byte\nclient.Call(ctx, req, &rawBytes)\njson.Unmarshal(rawBytes, &resp)","handlingStrategy":"type-guard","validationCode":"if _, ok := target.(*[]byte); !ok {\n    return fmt.Errorf(\"bytes codec response target must be *[]byte\")\n}","typeGuard":"func isBytePtr(v interface{}) bool {\n    _, ok := v.(*[]byte)\n    return ok\n}","tryCatchPattern":"err := client.Call(ctx, req, target)\nif err != nil && strings.Contains(err.Error(), \"failed to unmarshal\") {\n    // target must be *[]byte for the bytes codec\n}","preventionTips":["Match codecs on both ends of every call/subscription","Decode raw bytes into structs explicitly after receiving","Document codec choice per topic/service","Cover codec combinations in 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"}