apache/beam · error
Init hooks have already run. Register hook during init()…
Error message
Init hooks have already run. Register hook during init() instead.
What it means
runtime.RegisterInit queues hooks that run once when beam.Init() executes; after Init has run, the hooks slice is frozen (initialized=true). Registering later would silently never run, so the library panics to force registration in init() time.
Solutions
- Move the RegisterInit call into a package init() function so it runs before beam.Init().
- If you cannot use init(), ensure RegisterInit executes before any call to beam.Init() in main.
- Restructure so the hook's work happens after Init via a different mechanism (e.g. call the function directly after Init).
Example fix
// before
func main() {
beam.Init()
runtime.RegisterInit(myHook) // panics
}
// after
func init() {
runtime.RegisterInit(myHook)
}
func main() {
beam.Init()
} Defensive patterns
Strategy: validation
Validate before calling
// call only from package init(), before beam.Init()
func init() { runtime.RegisterInit(myHook) } Prevention
- Register all Init hooks in package init() functions
- Call beam.Init() exactly once, as late as reasonable in main
- Never register hooks from tests that run after TestMain's beam.Init()
When it happens
Trigger: Calling runtime.RegisterInit(func(){...}) from normal program flow (a test's Setup, a handler, main after beam.Init()) rather than from a package init() function.
Common situations: Moving beam.Init() earlier in main so it precedes registration; a lazily-imported package whose registration code runs post-Init; tests that call beam.Init() in TestMain and then register hooks in individual tests.
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
- AfterProcessingTime trigger set without a delay or…
- At least one subtrigger required for composite triggers.
- attempted to add namespace to missing coder id
- attempted to add namespace to missing windowing strategy id
- batch: failed to marshal worker UUID
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/a15e918326c0f62e.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/core/runtime/init.go:31
// See the License for the specific language governing permissions and
// limitations under the License.
// Package runtime contains runtime hooks and utilities for pipeline options
// and type registration. Most functionality done in init and hence is
// available both during pipeline-submission and at runtime.
package runtime
var (
hooks []func()
initialized bool
)
// RegisterInit registers an Init hook. Hooks are expected to be able to
// figure out whether they apply on their own, notably if invoked in a remote
// execution environment. They are all executed regardless of the runner.
func RegisterInit(hook func()) {
if initialized {
panic("Init hooks have already run. Register hook during init() instead.")
}
hooks = append(hooks, hook)
}
// Init is the hook that all user code must call after flags processing and
// other static initialization, for now.
func Init() {
initialized = true
for _, hook := range hooks {
hook()
}
}
// Initialized exposes the initialization status for runners.
func Initialized() bool {
return initialized
}View on GitHub (pinned to 12126d8942)