{"record":{"id":"bc73d7cbdda45fbb","repo":"geektutu/7days-golang","slug":"invalid-codec-type-s-bc73d7","errorCode":null,"errorMessage":"invalid codec type %s","messagePattern":"invalid codec type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-rpc/day3-service/client.go","lineNumber":205,"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\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),\n\t}","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-rpc/day3-service/client.go#L187-L223","documentation":"NewClient in gee-rpc/day3-service rejects an Option whose CodecType has no registered codec constructor, returning \"invalid codec type %s\". The client cannot negotiate a message codec with the server, so it aborts before sending options.","triggerScenarios":"Dial/DialHTTP-style connection via NewClient with opt.CodecType set to an unregistered string (e.g. \"application/json\" when only GobType is in NewCodecFuncMap).","commonSituations":"Client and server configured with different codec strings; hand-written Option with a typo; expecting JSON support that is not registered by default; custom codec registered only on one side.","solutions":["Use codec.GobType for opt.CodecType or leave it empty (defaults to Gob)","Register the desired codec in codec.NewCodecFuncMap before dialing, identically on client and server","Pass nil opts to Dial to accept DefaultOption","Cross-check the exact string constants in the codec package rather than hardcoding literals"],"exampleFix":"// before\nopt := &geerpc.Option{CodecType: \"application/json\"} // not registered\n// after\nimport \"geerpc/codec\"\nopt := &geerpc.Option{CodecType: codec.GobType}","handlingStrategy":"validation","validationCode":"if opt.CodecType != \"\" {\n\tif _, ok := codec.NewCodecFuncMap[opt.CodecType]; !ok {\n\t\treturn fmt.Errorf(\"unsupported codec %q\", opt.CodecType)\n\t}\n}\nclient, err := geerpc.Dial(\"tcp\", addr, opt)","typeGuard":"func codecSupported(t string) bool {\n\t_, ok := codec.NewCodecFuncMap[t]\n\treturn ok\n}","tryCatchPattern":"client, err := geerpc.Dial(\"tcp\", addr, opt)\nif err != nil && strings.Contains(err.Error(), \"invalid codec type\") {\n\topt.CodecType = \"\" // default to Gob via parseOptions\n\tclient, err = geerpc.Dial(\"tcp\", addr, opt)\n}","preventionTips":["Leave CodecType empty unless you intentionally registered a custom codec","Use shared constants for codec names across services","Test dialing in unit tests so bad codec configs fail at build/CI time","Never copy Option literals across day branches without checking codec support"],"tags":["rpc","configuration","codec"],"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"}