apache/beam · critical
type is not registered. Ensure that beam.RegisterType( ) is…
Error message
type %v is not registered. Ensure that beam.RegisterType(%v) is called before beam.Init().
What it means
checkTypeRegistered panics when the named struct type used with bigqueryio has not been registered with beam.RegisterType before beam.Init(). Beam's runtime needs a global type registry so worker binaries can decode/encode elements across processes; an unregistered type would fail during pipeline serialization/execution.
Solutions
- Add beam.RegisterType(reflect.TypeOf(MyRow{})) in an init() function or before beam.Init() in main.
- Verify the registration happens in the same binary that builds/runs the pipeline.
- Check that the type passed to Read/Write is exactly the registered type (not a type alias with a different identity).
Example fix
// before
func main() {
beam.Init()
bigqueryio.Write(s, proj, ds, table, col) // col elem type MyRow
}
// after
type MyRow struct{ N int }
func init() {
beam.RegisterType(reflect.TypeOf(MyRow{}))
}
func main() {
beam.Init()
bigqueryio.Write(s, proj, ds, table, col)
} Defensive patterns
Strategy: validation
Validate before calling
if _, ok := runtime.LookupType(runtime.TypeKey(reflectx.SkipPtr(reflect.TypeOf(MyRow{})))); !ok {
beam.RegisterType(reflect.TypeOf(MyRow{}))
} Try / catch
defer func() {
if r := recover(); r != nil {
if strings.Contains(fmt.Sprint(r), "is not registered") {
log.Fatalf("register the type with beam.RegisterType before beam.Init(): %v", r)
}
panic(r)
}
}() Prevention
- Put beam.RegisterType calls in each type's package init().
- Register every struct used as a PCollection element in distributed pipelines.
- Keep beam.Init() after all registrations in main().
When it happens
Trigger: Calling bigqueryio.Read or bigqueryio.Write with a named struct type T for which beam.RegisterType(reflect.TypeOf(T{})) was never called, then running with a distributed runner that requires registration.
Common situations: Forgetting the beam.RegisterType line in main() before beam.Init(); adding a new row struct to an existing pipeline; refactoring that moves the type into another package without re-registering it.
Related errors
- schema type must be struct
- type must be a named type (not anonymous) for registration
- requires either a Table or Query specified, received none
- AfterProcessingTime trigger set without a delay or…
- At least one subtrigger required for composite triggers.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/2626647ca42922c2.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/io/bigqueryio/bigquery.go:242
checkTypeRegistered(t)
schema, err := bigquery.InferSchema(reflect.Zero(t).Interface())
if err != nil {
panic(errors.Wrapf(err, "invalid schema type: %v", t))
}
return schema
}
func checkTypeRegistered(t reflect.Type) {
t = reflectx.SkipPtr(t)
key, ok := runtime.TypeKey(t)
if !ok {
panic(fmt.Sprintf("type %v must be a named type (not anonymous) for registration", t))
}
if _, registered := runtime.LookupType(key); !registered {
panic(fmt.Sprintf("type %v is not registered. Ensure that beam.RegisterType(%v) "+
"is called before beam.Init().", t, t))
}
}
func mustParseTable(table string) QualifiedTableName {
qn, err := NewQualifiedTableName(table)
if err != nil {
panic(err)
}
return qn
}
// TODO(herohde) 7/14/2017: allow WriteDispositions. The default
// is not quite what the Dataflow examples do.
// writeOptions represents additional options for executing a write
type writeOptions struct {
// CreateDisposition specifies the circumstances under which destination table will be createdView on GitHub (pinned to 12126d8942)