apache/beam · error
invalid registration type: %v
Error message
invalid registration type: %v
What it means
RegisterType derives a registry key via TypeKey(t), which only supports types with representable external keys (notably functions and certain unnamed/composite types are rejected). If no key can be derived, registering the type would be meaningless, so the library panics with the offending type.
Source
Thrown at sdks/go/pkg/beam/core/runtime/types.go:39
"github.com/apache/beam/sdks/v2/go/pkg/beam/core/util/reflectx"
)
var types = make(map[string]reflect.Type)
// RegisterType inserts "external" types into a global type registry to bypass
// serialization and preserve full method information. It should be called in
// init() only. Returns the external key for the type.
func RegisterType(t reflect.Type) string {
if initialized {
panic("Init hooks have already run. Register type during init() instead.")
}
t = reflectx.SkipPtr(t)
k, ok := TypeKey(t)
if !ok {
panic(fmt.Sprintf("invalid registration type: %v", t))
}
if v, exists := types[k]; exists && v != t {
panic(fmt.Sprintf("type already registered for %v, and new type %v != %v (existing type)", k, t, v))
}
types[k] = t
return k
}
// LookupType looks up a type in the global type registry by external key.
func LookupType(key string) (reflect.Type, bool) {
t, ok := types[key]
return t, ok
}
// TypeKey returns the external key of a given type. Returns false if not a
// candidate for registration.
func TypeKey(t reflect.Type) (string, bool) {View on GitHub (pinned to 12126d8942)
Solutions
- Register a named, concrete struct type (or pointer to it) instead of an anonymous/func/chan type.
- Use reflect.TypeOf on a concrete instance value, not on an interface variable, so the dynamic type is registered.
- If the type genuinely has no key (e.g. plain func), skip registry registration or wrap it in a named struct.
Example fix
// before
runtime.RegisterType(reflect.TypeOf(func(int) {})) // panics
// after
type MyFn struct{}
func (MyFn) ProcessElement(int) {}
runtime.RegisterType(reflect.TypeOf(MyFn{})) Defensive patterns
Strategy: type-guard
Validate before calling
t := reflect.TypeOf(val)
if t.Kind() == reflect.Func || t.Kind() == reflect.Chan || t.Name() == "" {
return fmt.Errorf("cannot register unsupported type %v", t)
} Type guard
func registrable(t reflect.Type) bool {
t = reflectx.SkipPtr(t)
_, ok := runtime.TypeKey(t) // same check the library performs
return ok
} Prevention
- Only register named concrete types (structs and their pointers)
- Avoid reflect.TypeOf on interface values or anonymous literals
- Check TypeKey success before calling RegisterType in wrapper code
When it happens
Trigger: Passing a reflect.Type that TypeKey cannot handle — typically a func type without a proper named signature, an unexported/anonymous type, or a similarly unsupported kind (e.g. chan, interface) — to runtime.RegisterType (directly or via RegisterDoFn/RegisterCoder).
Common situations: Registering anonymous struct or func literals with reflect.TypeOf; registering a variable of interface or channel type by mistake; calling RegisterType on a DoFn wrapper type that isn't a struct.
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
- Init hooks have already run. Register type during init() ins
- err
- Logical Types must be registered with interface types. %v is
- Logical Types may not be registered with empty interface typ
- Init hooks have already run. Register function during init()
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/ea9e9c0180b2541c.
Report an issue: GitHub.