{"record":{"id":"b5e8f11a0031ba1e","repo":"grpc/grpc-go","slug":"cannot-register-codec-with-empty-string-result-for","errorCode":null,"errorMessage":"cannot register Codec with empty string result for Name()","messagePattern":"cannot register Codec with empty string result for Name\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"encoding/encoding.go","lineNumber":137,"sourceCode":"// servers.\n//\n// The Codec will be stored and looked up by result of its Name() method, which\n// should match the content-subtype of the encoding handled by the Codec.  This\n// is case-insensitive, and is stored and looked up as lowercase.  If the\n// result of calling Name() is an empty string, RegisterCodec will panic. See\n// Content-Type on\n// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests for\n// more details.\n//\n// NOTE: this function must only be called during initialization time (i.e. in\n// an init() function), and is not thread-safe.  If multiple Codecs are\n// registered with the same name, the one registered last will take effect.\nfunc RegisterCodec(codec Codec) {\n\tif codec == nil {\n\t\tpanic(\"cannot register a nil Codec\")\n\t}\n\tif codec.Name() == \"\" {\n\t\tpanic(\"cannot register Codec with empty string result for Name()\")\n\t}\n\tcontentSubtype := strings.ToLower(codec.Name())\n\tregisteredCodecs[contentSubtype] = codec\n}\n\n// GetCodec gets a registered Codec by content-subtype, or nil if no Codec is\n// registered for the content-subtype.\n//\n// The content-subtype is expected to be lowercase.\nfunc GetCodec(contentSubtype string) Codec {\n\tc, _ := registeredCodecs[contentSubtype].(Codec)\n\treturn c\n}\n","sourceCodeStart":119,"sourceCodeEnd":151,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/encoding/encoding.go#L119-L151","documentation":"encoding.RegisterCodec (encoding.go:132) panics if codec.Name() returns an empty string (checked at encoding.go:137). The Name() result is the content-subtype used as the map key and in the Content-Type header (e.g. 'proto', 'json'); an empty name would be unaddressable and break codec lookup.","triggerScenarios":"Registering a Codec whose Name() method returns \"\" (e.g. a struct whose name field was never set, or a Name() implementation that returns a zero-value string).","commonSituations":"A codec built from config where the name field defaulted to empty; copy-pasting a codec template and forgetting to implement Name() to return a real value; a codec whose name is computed from an uninitialized variable.","solutions":["Ensure the codec's Name() returns a non-empty, content-subtype-valid string (e.g. \"json\").","If the name comes from config, validate it is non-empty before registering.","Add a unit test asserting codec.Name() != \"\" before calling RegisterCodec."],"exampleFix":"// before\ntype myCodec struct{ name string }\nfunc (m *myCodec) Name() string { return m.name } // empty when unset\nfunc init() { encoding.RegisterCodec(&myCodec{}) } // panics\n\n// after\nfunc init() { encoding.RegisterCodec(&myCodec{name: \"myjson\"}) }","handlingStrategy":"validation","validationCode":"func init() {\n    c := buildCodec()\n    if c.Name() == \"\" {\n        log.Fatal(\"codec Name() is empty\")\n    }\n    encoding.RegisterCodec(c)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Implement Name() to return a literal non-empty content-subtype.","Validate any config-sourced name before registering.","Add a test asserting codec.Name() is non-empty."],"tags":["encoding","codec","panic","grpc-go","init","validation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}