{"record":{"id":"0e6b9e9db7eeddab","repo":"apache/beam","slug":"newsk-keycoder-must-not-be-nil","errorCode":null,"errorMessage":"NewSK: keyCoder must not be nil","messagePattern":"NewSK: keyCoder must not be nil","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/core/graph/coder/coder.go","lineNumber":533,"sourceCode":"func NewCoGBK(components []*Coder) *Coder {\n\tcheckCodersNotNil(components)\n\treturn &Coder{\n\t\tKind:       CoGBK,\n\t\tT:          typex.New(typex.CoGBKType, Types(components)...),\n\t\tComponents: components,\n\t}\n}\n\n// NewSK returns a coder for ShardedKey-typed values. The component\n// keyCoder encodes the user key; the ShardID is encoded as a\n// length-prefixed byte string preceding it (beam:coder:sharded_key:v1).\n//\n// The resulting FullType root is typex.ShardedKeyType with the key's\n// FullType as the single component, following the same Composite\n// pattern as KV.\nfunc NewSK(keyCoder *Coder) *Coder {\n\tif keyCoder == nil {\n\t\tpanic(\"NewSK: keyCoder must not be nil\")\n\t}\n\treturn &Coder{\n\t\tKind:       ShardedKey,\n\t\tT:          typex.New(typex.ShardedKeyType, keyCoder.T),\n\t\tComponents: []*Coder{keyCoder},\n\t}\n}\n\n// IsSK returns true iff the coder is for a ShardedKey.\nfunc IsSK(c *Coder) bool {\n\treturn c != nil && c.Kind == ShardedKey\n}\n\n// SkipW returns the data coder used by a WindowedValue, or returns the coder. This\n// allows code to seamlessly traverse WindowedValues without additional conditional\n// code.\nfunc SkipW(c *Coder) *Coder {\n\tif c.Kind == WindowedValue {","sourceCodeStart":515,"sourceCodeEnd":551,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/core/graph/coder/coder.go#L515-L551","documentation":"NewSK in sdks/go/pkg/beam/core/graph/coder/coder.go panics with \"NewSK: keyCoder must not be nil\" when constructing a ShardedKey coder without a key coder. A ShardedKey coder is a composite whose single component is the key's coder, mirroring KV, so nil is invalid. The panic is a fail-fast constructor contract check.","triggerScenarios":"Calling coder.NewSK(nil) directly or via makeCoder in tests, or passing a key coder from a failed lookup that returned nil with its error ignored.","commonSituations":"Pipelines using sharded keys (TryCombinePerKey outputs, TestShardedKeyCoder_WireFormat) where key-coder wiring was assembled dynamically and lost initialization.","solutions":["Build the key coder before NewSK: kc := coder.NewJ(keyType); skc := coder.NewSK(kc).","Fix the code producing the nil key coder — check every (coder, err) return for swallowed errors.","Add a nil assertion before the call to surface the problem with more context."],"exampleFix":"// before\nskc := coder.NewSK(nil) // panics\n// after\nkc := coder.NewJ(reflect.TypeOf(\"\"))\nskc := coder.NewSK(kc)","handlingStrategy":"validation","validationCode":"if kc == nil {\n    return nil, errors.New(\"key coder must be initialized before NewSK\")\n}\nskc := coder.NewSK(kc)","typeGuard":"func isCoderReady(c *coder.Coder) bool { return c != nil && c.T != nil }","tryCatchPattern":"func newSKSafe(kc *coder.Coder) (skc *coder.Coder, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"NewSK failed: %v\", r)\n        }\n    }()\n    return coder.NewSK(kc), nil\n}","preventionTips":["Construct the key coder with NewJ/NewKV before calling NewSK.","Check (coder, err) returns so nil key coders never propagate.","Add unit tests for sharded-key coder construction paths (mirroring TestSK_IsDeterministic)."],"tags":["go","apache-beam","coder","nil-check","sharded-key"],"backgroundTag":"null-argument","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}