apache/beam · error

bad decode

Error message

bad decode

What it means

NewCustomCoder wraps any error from converting the decode function via funcx.New(reflectx.MakeFunc(decode)) with "bad decode". It means the decode function could not be converted into an internal callable — usually nil or not a function. It fires only after validateDecoder succeeds, so it indicates a structurally invalid function value.

Source

Thrown at sdks/go/pkg/beam/core/graph/coder/coder.go:159

}

// NewCustomCoder creates a coder for the supplied parameters defining a
// particular encoding strategy.
func NewCustomCoder(id string, t reflect.Type, encode, decode any) (*CustomCoder, error) {
	if err := validateEncoder(t, encode); err != nil {
		return nil, errors.WithContext(err, "NewCustomCoder")
	}
	enc, err := funcx.New(reflectx.MakeFunc(encode))
	if err != nil {
		return nil, errors.Wrap(err, "bad encode")
	}
	if err := validateDecoder(t, decode); err != nil {
		return nil, errors.WithContext(err, "NewCustomCoder")
	}

	dec, err := funcx.New(reflectx.MakeFunc(decode))
	if err != nil {
		return nil, errors.Wrap(err, "bad decode")
	}

	c := &CustomCoder{
		Name: id,
		Type: t,
		Enc:  enc,
		Dec:  dec,
	}
	return c, nil
}

// NewCustomCoderWithFuncs creates a CustomCoder from pre-wrapped
// reflectx.Func values. This allows the caller to control the Name()
// returned by each function — critical for closures inside Go generic
// functions where the compiler assigns identical names to different
// type instantiations.
func NewCustomCoderWithFuncs(id string, t reflect.Type, enc, dec *funcx.Fn) *CustomCoder {
	return &CustomCoder{

View on GitHub (pinned to 12126d8942)

Solutions

  1. Ensure decode is a non-nil Go function with signature func([]byte) T (or compatible)
  2. Check the encode/decode arguments are not swapped
  3. Inspect the wrapped underlying error for the exact funcx failure

Example fix

// before
var decodeFn func([]byte) T
cc, err := coder.NewCustomCoder("myCoder", t, encodeFn, decodeFn)
// after
decodeFn := func(b []byte) T { var v T; decodeInto(b, &v); return v }
cc, err := coder.NewCustomCoder("myCoder", t, encodeFn, decodeFn)
Defensive patterns

Strategy: validation

Validate before calling

if decode == nil { return errors.New("decode must be a non-nil func") }
if rv := reflect.ValueOf(decode); rv.Kind() != reflect.Func { return fmt.Errorf("decode must be a func, got %v", rv.Kind()) }

Type guard

func isFunc(v any) bool { return v != nil && reflect.ValueOf(v).Kind() == reflect.Func }

Prevention

When it happens

Trigger: Passing a nil decode function or a non-function value as the decode parameter of NewCustomCoder.

Common situations: Declaring the decode func variable without initializing it, or swapping encode/decode arguments so the functions land in the wrong slots in a way funcx rejects.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/6048dd0262fe5580. Report an issue: GitHub.