{"record":{"id":"a4530a72e68fe881","repo":"grpc/grpc-go","slug":"cannot-register-codecv2-with-empty-string-result-f","errorCode":null,"errorMessage":"cannot register CodecV2 with empty string result for Name()","messagePattern":"cannot register CodecV2 with empty string result for Name\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"encoding/encoding_v2.go","lineNumber":68,"sourceCode":"// should match the content-subtype of the encoding handled by the CodecV2.  This\n// is case-insensitive, and is stored and looked up as lowercase.  If the\n// result of calling Name() is an empty string, RegisterCodecV2 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// If both a Codec and CodecV2 are registered with the same name, the CodecV2\n// will be used.\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 RegisterCodecV2(codec CodecV2) {\n\tif codec == nil {\n\t\tpanic(\"cannot register a nil CodecV2\")\n\t}\n\tif codec.Name() == \"\" {\n\t\tpanic(\"cannot register CodecV2 with empty string result for Name()\")\n\t}\n\tcontentSubtype := strings.ToLower(codec.Name())\n\tregisteredCodecs[contentSubtype] = codec\n}\n\n// GetCodecV2 gets a registered CodecV2 by content-subtype, or nil if no CodecV2 is\n// registered for the content-subtype.\n//\n// The content-subtype is expected to be lowercase.\nfunc GetCodecV2(contentSubtype string) CodecV2 {\n\tc, _ := registeredCodecs[contentSubtype].(CodecV2)\n\treturn c\n}\n","sourceCodeStart":50,"sourceCodeEnd":82,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/encoding/encoding_v2.go#L50-L82","documentation":"encoding.RegisterCodecV2 (encoding_v2.go:63) panics when codec.Name() returns \"\" (encoding_v2.go:68), mirroring RegisterCodec. The Name() result is the content-subtype used as the registry key and Content-Type header value; empty is unusable.","triggerScenarios":"Registering a CodecV2 whose Name() returns an empty string, typically because an internal name field was never set.","commonSituations":"A V2 codec adapted from config with a defaulted-empty name; a stub Name() left from scaffolding; the name sourced from an env var that was unset.","solutions":["Make Name() return a non-empty content-subtype (e.g. \"proto\").","Validate the name is non-empty before registering, especially when it comes from configuration.","Unit-test that the codec reports a non-empty name."],"exampleFix":"// before\ntype c2 struct{}\nfunc (*c2) Name() string { return \"\" } // empty\nfunc init() { encoding.RegisterCodecV2(&c2{}) } // panics\n\n// after\nfunc (*c2) Name() string { return \"myproto\" }\nfunc init() { encoding.RegisterCodecV2(&c2{}) }","handlingStrategy":"validation","validationCode":"func init() {\n    c := buildCodecV2()\n    if c.Name() == \"\" {\n        log.Fatal(\"codecv2 Name() is empty\")\n    }\n    encoding.RegisterCodecV2(c)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Return a literal non-empty content-subtype from Name().","Validate config-derived names before registering.","Test that CodecV2 reports a non-empty name."],"tags":["encoding","codec","codecv2","panic","grpc-go","init","validation"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}