{"record":{"id":"83cc741ff45be740","repo":"geektutu/7days-golang","slug":"invalid-codec-type-s-83cc74","errorCode":null,"errorMessage":"invalid codec type %s","messagePattern":"invalid codec type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-rpc/day5-http-debug/client.go","lineNumber":216,"sourceCode":"\t// if opts is nil or pass nil as parameter\n\tif len(opts) == 0 || opts[0] == nil {\n\t\treturn DefaultOption, nil\n\t}\n\tif len(opts) != 1 {\n\t\treturn nil, errors.New(\"number of options is more than 1\")\n\t}\n\topt := opts[0]\n\topt.MagicNumber = DefaultOption.MagicNumber\n\tif opt.CodecType == \"\" {\n\t\topt.CodecType = DefaultOption.CodecType\n\t}\n\treturn opt, nil\n}\n\nfunc NewClient(conn net.Conn, opt *Option) (*Client, error) {\n\tf := codec.NewCodecFuncMap[opt.CodecType]\n\tif f == nil {\n\t\terr := fmt.Errorf(\"invalid codec type %s\", opt.CodecType)\n\t\tlog.Println(\"rpc client: codec error:\", err)\n\t\treturn nil, err\n\t}\n\t// send options with server\n\tif err := json.NewEncoder(conn).Encode(opt); err != nil {\n\t\tlog.Println(\"rpc client: options error: \", err)\n\t\t_ = conn.Close()\n\t\treturn nil, err\n\t}\n\treturn newClientCodec(f(conn), opt), nil\n}\n\nfunc newClientCodec(cc codec.Codec, opt *Option) *Client {\n\tclient := &Client{\n\t\tseq:     1, // seq starts with 1, 0 means invalid call\n\t\tcc:      cc,\n\t\topt:     opt,\n\t\tpending: make(map[uint64]*Call),","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day5-http-debug/client.go#L198-L234","documentation":"day5-http-debug's NewClient rejects an unregistered opt.CodecType with \"invalid codec type %s\". It is also invoked by NewHTTPClient, so HTTP-based connections hit the same codec-lookup rule as plain TCP dials.","triggerScenarios":"Dial or NewHTTPClient with an Option whose CodecType string is not a key in codec.NewCodecFuncMap (empty string is defaulted to Gob by parseOptions, any other unknown string fails).","commonSituations":"Hardcoding codec names instead of using codec package constants; assuming JSON/protobuf support exists when only Gob is registered; client binary missing the codec registration the server uses.","solutions":["Use codec.GobType (the default) for CodecType","Register the wanted codec in codec.NewCodecFuncMap before connecting","Pass no Option (or nil) to use DefaultOption","Keep client and server codec constants in a shared package to avoid string drift"],"exampleFix":"// before\nopt := &geerpc.Option{CodecType: \"protobuf\"} // never registered\n// after\nopt := &geerpc.Option{CodecType: codec.GobType}","handlingStrategy":"validation","validationCode":"if _, ok := codec.NewCodecFuncMap[opt.CodecType]; opt.CodecType != \"\" && !ok {\n\treturn fmt.Errorf(\"codec %q not registered\", opt.CodecType)\n}\nclient, err := geerpc.DialHTTP(\"tcp\", addr, opt)","typeGuard":"func codecSupported(t string) bool {\n\t_, ok := codec.NewCodecFuncMap[t]\n\treturn ok\n}","tryCatchPattern":"client, err := geerpc.NewHTTPClient(conn, opt)\nif err != nil && strings.Contains(err.Error(), \"invalid codec type\") {\n\topt.CodecType = codec.GobType\n\tclient, err = geerpc.NewHTTPClient(conn, opt)\n}","preventionTips":["Same validation for DialHTTP/NewHTTPClient as for plain Dial","Use codec constants; empty CodecType safely defaults to Gob","Register custom codecs identically on client and server","Cover client construction in unit tests to catch bad codec strings early"],"tags":["rpc","configuration","codec","http"],"backgroundTag":"invalid-codec-type","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}