apache/beam · error

%T isn't a supported encoder function type

Error message

%T isn't a supported encoder function type (passed with %v)

What it means

RowEncoderBuilder.Register panics when f is not an encoderProvider, i.e. not the expected func(reflect.Type) func(T, io.Writer) (error) factory shape. The builder stores custom encoder factories keyed by reflect.Type and requires this exact factory signature.

Solutions

  1. Change f to the encoderProvider factory shape func(reflect.Type) func(T, io.Writer) error
  2. Wrap the existing encoder in a factory closure matching encoderProvider
  3. Check the installed Beam version's encoderProvider definition

Example fix

// before
b.Register(reflect.TypeOf(Foo{}), func(f Foo, w io.Writer) error { ... })
// after
b.Register(reflect.TypeOf(Foo{}), func(rt reflect.Type) func(Foo, io.Writer) error {
	return func(f Foo, w io.Writer) error { ... }
})
Defensive patterns

Strategy: validation

Validate before calling

// compile-time shape check against encoderProvider
var _ rowcoder.EncoderProvider = myEncoderProviderFunc

Type guard

if _, ok := f.(encoderProvider); !ok {
	return fmt.Errorf("f must be an encoderProvider factory")
}

Try / catch

func safeRegister(b *rowcoder.RowEncoderBuilder, rt reflect.Type, f any) (err error) {
	defer func() { if r := recover(); r != nil { err = fmt.Errorf("register encoder: %v", r) } }()
	b.Register(rt, f)
	return nil
}

Prevention

When it happens

Trigger: Calling row_encoder_builder.Register(rt, f) where f is a plain encode function func(T, io.Writer) error instead of a provider factory, a method value, or another non-matching function type.

Common situations: Passing a direct encoder written against an older Beam API; confusing Register's factory signature with the per-instance encoder signature; migrating code between Beam versions where provider types changed.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

	// destination structs will be silently ignored when decoding.
	// This has no effect on types with registered decoder providers.
	RequireAllFieldsExported bool
}

type encoderProvider = func(reflect.Type) (func(any, io.Writer) error, error)

// Register accepts a provider for the given type to schema encode values of that type.
//
// When generating encoding functions, this builder will first check for exact type
// matches, then against interfaces with registered factories in recency order of
// registration, and then finally use 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 of the type func(reflect.Type) func(T, io.Writer) (error).
func (b *RowEncoderBuilder) Register(rt reflect.Type, f any) {
	fe, ok := f.(encoderProvider)
	if !ok {
		panic(fmt.Sprintf("%T isn't a supported encoder function type (passed with %v)", f, rt))
	}

	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]encoderProvider)
	}
	b.allFuncs[rt] = fe
	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 *RowEncoderBuilder) Build(rt reflect.Type) (func(any, io.Writer) error, error) {
	if err := rowTypeValidation(rt, true); err != nil {

View on GitHub (pinned to 12126d8942)