apache/beam · error

Init hooks have already run. Register type during init() ins

Error message

Init hooks have already run. Register type during init() instead.

What it means

runtime.RegisterType stores reflect.Type values in a global registry keyed by an external type key so serialized pipelines preserve full method info across process boundaries. Like the other registries it freezes once beam.Init() runs; late registration would make worker/driver registries inconsistent, so it panics.

Source

Thrown at sdks/go/pkg/beam/core/runtime/types.go:32

// limitations under the License.

package runtime

import (
	"fmt"
	"reflect"

	"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) {

View on GitHub (pinned to 12126d8942)

Solutions

  1. Move all RegisterType calls into package init() functions.
  2. Make sure beam.Init() runs only after all packages performing registration are imported.
  3. For tests, rely on init()-time registration rather than per-test setup that runs after Init.

Example fix

// before
func main() {
    beam.Init()
    runtime.RegisterType(reflect.TypeOf(MyType{})) // panics
}
// after
func init() {
    runtime.RegisterType(reflect.TypeOf(MyType{}))
}
func main() {
    beam.Init()
}
Defensive patterns

Strategy: validation

Validate before calling

// ensure call site is a package init() function:
func init() { runtime.RegisterType(reflect.TypeOf(MyType{})) }

Prevention

When it happens

Trigger: Calling runtime.RegisterType(t) (or wrappers RegisterDoFn/RegisterCoder/registerType that call it) after beam.Init() has executed, e.g. registering custom types/coders inside main post-Init or in tests after TestMain ran Init.

Common situations: Custom coder registration placed after beam.Init(); test files registering types lazily; plugin or module code whose init order relative to the main package's explicit beam.Init() call puts registration too late.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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