{"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/0c51461d27177d997e14c642fe18c11668fc09a3/encoding/encoding.go#L119-L151","documentation":"RegisterCodec stores the codec under strings.ToLower(codec.Name()), and that string becomes the content-subtype in the gRPC Content-Type header (e.g. application/grpc+proto). An empty Name() cannot form a valid content-subtype and would be unlook-up-able, so RegisterCodec panics at encoding/encoding.go:136-138 when codec.Name() returns empty. Name() must also be static (identical on every call).","triggerScenarios":"A Codec whose Name() returns an unset struct field (e.g. `return c.name` where name was never set), a stubbed empty return, or a name computed from an empty env var / config value.","commonSituations":"Prototyping a codec and leaving Name() stubbed; deriving the name from a flag/ENV/config that is empty in the current environment; copy-pasting a codec and forgetting to rename it.","solutions":["Make Name() return a constant non-empty lowercase identifier (e.g. json, proto).","Ensure the value is static across calls and set before the codec is registered.","If the name comes from config, validate it is non-empty at construction and fail loudly before RegisterCodec."],"exampleFix":"// before\nfunc (c flatCodec) Name() string { return c.configuredName } // empty -> panic\n\n// after\nfunc (c flatCodec) Name() string { return \"flat\" }","handlingStrategy":"validation","validationCode":"// Guard before registering a Codec.\nfunc registerSafe(c encoding.Codec) {\n    if c == nil || c.Name() == \"\" {\n        log.Printf(\"skipping registration: invalid codec name\")\n        return\n    }\n    encoding.RegisterCodec(c)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Return a string constant from Name() (e.g. proto, json) and keep it lowercase.","If the name comes from config, validate non-empty at construction and fail before registering.","Ensure Name() is static - the same identifier on every call."],"tags":["encoding","codec","registration","panic","content-type","go"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}