apache/beam · error
interface type must have methods
Error message
interface type %v must have methods
What it means
RowDecoderBuilder.Register panics when rt is the empty interface type (interface{}) with no methods. An empty interface cannot be decoded because the SDK cannot determine a concrete representation or schema for it, so registering a decoder factory for it is rejected.
Solutions
- Pass the concrete struct type instead of interface{} (e.g. reflect.TypeOf(Foo{}))
- In generic code, capture the concrete type via a typed parameter or type switch before calling Register
Example fix
// before
b.Register(reflect.TypeOf((*any)(nil)).Elem(), decFn)
// after
b.Register(reflect.TypeOf(Foo{}), decFn) Defensive patterns
Strategy: validation
Validate before calling
if rt.Kind() == reflect.Interface && rt.NumMethod() == 0 {
return fmt.Errorf("cannot register decoder for empty interface %v", rt)
} Type guard
func isRegisterableType(rt reflect.Type) bool {
return rt != nil && !(rt.Kind() == reflect.Interface && rt.NumMethod() == 0)
} Try / catch
func safeRegister(b *rowcoder.RowDecoderBuilder, rt reflect.Type, f any) (err error) {
defer func() { if r := recover(); r != nil { err = fmt.Errorf("register: %v", r) } }()
b.Register(rt, f)
return nil
} Prevention
- Never register decoders against interface{}; use concrete struct types
- In generic helpers, resolve the concrete type before calling Register
When it happens
Trigger: Calling b.Register(reflect.TypeOf((*any)(nil)).Elem(), decoderFn) or otherwise passing reflect.TypeOf of an empty interface type while registering row decoders.
Common situations: Generic helper code that stores the element type as any/interface{} and passes it through to Register without narrowing to the concrete element type.
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
- interface type must have methods
- bad decode
- bad encode
- cannot make schema encoder for type
- cannot make schema encoder for type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d187e550c640988b.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/graph/coder/row_decoder.go:57
// Register accepts a provider to decode schema encoded values
// of that type.
//
// When decoding values, decoder functions produced by this builder will
// first check for exact type matches, then interfaces implemented by
// the type in recency order of registration, and then finally the
// default Beam Schema encoding behavior.
//
// TODO(BEAM-9615): Add final factory types. This interface is subject to change.
// Currently f must be a function func(reflect.Type) (func(io.Reader) (any, error), error)
func (b *RowDecoderBuilder) Register(rt reflect.Type, f any) {
fd, ok := f.(decoderProvider)
if !ok {
panic(fmt.Sprintf("%T isn't a supported decoder function type (passed with %v), currently expecting %T", f, rt, (decoderProvider)(nil)))
}
if rt.Kind() == reflect.Interface && rt.NumMethod() == 0 {
panic(fmt.Sprintf("interface type %v must have methods", rt))
}
if b.allFuncs == nil {
b.allFuncs = make(map[reflect.Type]decoderProvider)
}
b.allFuncs[rt] = fd
if rt.Kind() == reflect.Interface {
b.ifaceFuncs = append(b.ifaceFuncs, rt)
}
}
// Build constructs a Beam Schema coder for the given type, using any providers registered for
// itself or it's fields.
func (b *RowDecoderBuilder) Build(rt reflect.Type) (func(io.Reader) (any, error), error) {
if err := rowTypeValidation(rt, true); err != nil {
return nil, err
}
return b.decoderForType(rt)View on GitHub (pinned to 12126d8942)