apache/beam · error
nil coder at index
Error message
nil coder at index: %v
What it means
checkCodersNotNil is an internal invariant check that panics when a composite coder (KV, N, or CoGBK) is constructed with a nil element coder. The Apache Beam Go SDK requires every component coder of a composite type to be a fully-formed *Coder so the pipeline can serialize all elements. A nil in the list means the caller passed an unconstructed or unset coder.
Solutions
- Find the coder at the index printed in the panic and fix why it is nil (failed lookup, wrong variable, skipped initialization)
- Ensure every component coder is constructed via coder.New* before building the composite coder
- If the type is unsupported, use coder.NewUnknown instead of passing nil
- Add a non-nil check/log before composing coders in custom pipeline code
Example fix
// before
c := coder.NewKV(kvCoder[0], kvCoder[1]) // kvCoder[1] may be nil
// after
if kvCoder[0] == nil || kvCoder[1] == nil {
log.Fatalf("component coder missing")
}
c := coder.NewKV(kvCoder[0], kvCoder[1]) Defensive patterns
Strategy: validation
Validate before calling
for i, c := range coders {
if c == nil {
return fmt.Errorf("coder at index %d is nil", i)
}
} Type guard
func hasNilCoder(list []*coder.Coder) bool {
for _, c := range list {
if c == nil {
return true
}
}
return false
} Try / catch
// Go panics are not recoverable at the call site unless wrapped:
func safeNewKV(list []*coder.Coder) (c *coder.Coder, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("checkCodersNotNil: %v", r)
}
}()
return coder.NewKV(list[0], list[1]), nil
} Prevention
- Initialize all component coders before composing composite coders
- Use coder.NewUnknown rather than nil for unknown types
- Check registry/map lookups for coder types before use
When it happens
Trigger: Calling coder.NewKV(nil, v), coder.NewN(nil), coder.NewCoGBK(nil, ...) or any composite constructor with a nil entry anywhere in the coder slice; the panic fires during pipeline graph construction with the offending slice index.
Common situations: Building custom transforms where a component coder comes from a map/registry lookup that missed; conditional logic that leaves a coder variable nil on some paths; refactoring that reordered coder construction so one is used before assignment.
Related errors
- bad coder kind
- bad decoding function
- bad encoding function
- bad window kind
- could not unmarshal coder from
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/bb0571406f5dc164.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/graph/coder/coder.go:574
// CoderFrom is a helper that creates a Coder from a CustomCoder.
func CoderFrom(c *CustomCoder) *Coder {
return &Coder{Kind: Custom, T: typex.New(c.Type), Custom: c}
}
// Types returns a slice of types used by the supplied coders.
func Types(list []*Coder) []typex.FullType {
var ret []typex.FullType
for _, c := range list {
ret = append(ret, c.T)
}
return ret
}
func checkCodersNotNil(list []*Coder) {
for i, c := range list {
if c == nil {
panic(fmt.Sprintf("nil coder at index: %v", i))
}
}
}
View on GitHub (pinned to 12126d8942)