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
- Ensure decode is a non-nil Go function with signature func([]byte) T (or compatible)
- Check the encode/decode arguments are not swapped
- 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
- Initialize decode functions before registration
- Keep encode/decode adjacent in code so order errors are visible
- Match the decode signature func([]byte) T exactly
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
- bad encode
- inferCoder failed: interface type %v has no coder registered
- errIllegalParametersInIter
- Type %v of kind %v not allowed, must be ptr type
- not a function: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/6048dd0262fe5580.
Report an issue: GitHub.