apache/beam · error
RegisterTraceCaptureHook
Error message
RegisterTraceCaptureHook: %s registered twice
What it means
RegisterTraceCaptureHook stores a trace CaptureHookFactory in traceCaptureHookRegistry and panics if the same identifier is already registered. Like the profile hook registry, it is designed to fail fast at init time when two code paths claim the same hook name.
Solutions
- Locate all call sites registering that trace hook name and keep exactly one.
- Move registration to a single package init and rely on blank imports elsewhere.
- Deduplicate the dependency tree if two versions of the hook package are both linked.
- Wrap dynamic registrations in sync.Once or check registration state before calling.
Example fix
// before
perf.RegisterTraceCaptureHook("mytrace", f)
perf.RegisterTraceCaptureHook("mytrace", g) // panics
// after
perf.RegisterTraceCaptureHook("mytrace", f) // single registration only Defensive patterns
Strategy: validation
Validate before calling
if _, exists := traceRegistered["mytrace"]; !exists {
perf.RegisterTraceCaptureHook("mytrace", myFactory)
} Try / catch
func registerTrace(name string, f perf.CaptureHookFactory) {
defer func() {
if r := recover(); r != nil {
log.Printf("trace hook %q duplicate registration ignored: %v", name, r)
}
}()
perf.RegisterTraceCaptureHook(name, f)
} Prevention
- One registration site per hook name, ideally a package init.
- Avoid registering in test helpers that run in the same process as production init.
- Deduplicate dependencies to prevent two copies of the hook package running init.
- Track registration in your own set/map as a pre-check.
When it happens
Trigger: Calling perf.RegisterTraceCaptureHook(name, factory) with a name already in traceCaptureHookRegistry — duplicate init() registrations, a test helper registering a hook that production init also registers, or two copies of the hook package linked via different module versions.
Common situations: Multiple instrumentation packages registering identically-named trace hooks; re-registering during test re-runs within the same process; vendored forks of a hook package both executing init.
Related errors
- RegisterHeapCaptureHook
- RegisterProfCaptureHook
- Beam has not been initialized. Call beam.Init() before…
- Init hooks have already run. Register hook during init()…
- while executing Up for
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0148ead5b79a1068.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/x/hooks/perf/perf.go:177
enabledProfCaptureHooks[i] = enc
hooks.EnableHook("prof", enabledProfCaptureHooks...)
return
}
}
enabledProfCaptureHooks = append(enabledProfCaptureHooks, enc)
hooks.EnableHook("prof", enabledProfCaptureHooks...)
}
var traceCaptureHookRegistry = make(map[string]CaptureHookFactory)
var enabledTraceCaptureHooks []string
// RegisterTraceCaptureHook registers a CaptureHookFactory for the
// supplied identifier. It panics if the same identifier is
// registered twice.
func RegisterTraceCaptureHook(name string, c CaptureHookFactory) {
if _, exists := traceCaptureHookRegistry[name]; exists {
panic(fmt.Sprintf("RegisterTraceCaptureHook: %s registered twice", name))
}
traceCaptureHookRegistry[name] = c
}
// EnableTraceCaptureHook actives a registered profile capture hook for a given pipeline.
func EnableTraceCaptureHook(name string, opts ...string) {
if _, exists := traceCaptureHookRegistry[name]; !exists {
panic(fmt.Sprintf("EnableTraceCaptureHook: %s not registered", name))
}
enc := hooks.Encode(name, opts)
for i, h := range enabledTraceCaptureHooks {
n, _ := hooks.Decode(h)
if h == n {
// Rewrite the registration with the current arguments
enabledTraceCaptureHooks[i] = enc
hooks.EnableHook("trace", enabledTraceCaptureHooks...)
returnView on GitHub (pinned to 12126d8942)