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

  1. Find the coder at the index printed in the panic and fix why it is nil (failed lookup, wrong variable, skipped initialization)
  2. Ensure every component coder is constructed via coder.New* before building the composite coder
  3. If the type is unsupported, use coder.NewUnknown instead of passing nil
  4. 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

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


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)