apache/beam · error

EnableHook: not registered

Error message

EnableHook: %s not registered

What it means

EnableHook activates a registered gRPC hook by name and panics if the name was never passed to RegisterHook. It ensures hooks can only be enabled after their factories are registered in the global registry.

Solutions

  1. Import the package that registers the hook (side-effect import: _ "path/to/hook") so its init() runs
  2. Verify the hook name string matches a registered identifier exactly
  3. Call RegisterHook before EnableHook for custom hooks
  4. Check build tags/files to ensure the registration code is compiled into the binary

Example fix

// before
func main() {
	grpcx.EnableHook("custom-hook") // panics: not registered
}
// after
import _ "example.com/beam/hooks/custom"
func main() {
	grpcx.EnableHook("custom-hook")
}
Defensive patterns

Strategy: try-catch

Validate before calling

if !hookIsRegistered(name) {
	return fmt.Errorf("hook %q must be registered before EnableHook", name)
}

Try / catch

defer func() {
	if r := recover(); r != nil {
		err = fmt.Errorf("EnableHook failed: %v", r)
	}
}()

Prevention

When it happens

Trigger: Calling grpcx.EnableHook("my-hook") when RegisterHook("my-hook", ...) was never executed — e.g. enabling a built-in hook name in a binary that doesn't import the package containing its init(), or a typo in the hook name.

Common situations: Enabling hooks via pipeline options in a custom runner binary missing the hook package import; misspelled hook identifier; Go build excluding the file whose init() registers the hook (build tags).

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at sdks/go/pkg/beam/util/grpcx/hook.go:75

				name, opts := hooks.Decode(opts[0])
				grpcHook := hookRegistry[name](opts)
				if grpcHook.Dialer != nil {
					Dial = grpcHook.Dialer
				}
				return ctx, nil
			},
		}
	}
	hooks.RegisterHook("grpc", hf)
}

// EnableHook is called to request the use of the gRPC
// hook in a pipeline.
func EnableHook(name string, opts ...string) {
	_, exists := hookRegistry[name]
	if !exists {
		panic(fmt.Sprintf("EnableHook: %s not registered", name))
	}
	// Only one hook can be enabled. If the pipeline has two conflicting views about how to use gRPC
	// that won't end well.
	if exists, opts := hooks.IsEnabled("grpc"); exists {
		n, _ := hooks.Decode(opts[0])
		if n != name {
			panic(fmt.Sprintf("EnableHook: can't enable hook %s, hook %s already enabled", name, n))
		}
	}

	hooks.EnableHook("grpc", hooks.Encode(name, opts))
}

View on GitHub (pinned to 12126d8942)