{"record":{"id":"ad768a6b4871421d","repo":"apache/beam","slug":"enablehook-s-not-registered","errorCode":null,"errorMessage":"EnableHook: %s not registered","messagePattern":"EnableHook: (.+?) not registered","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/util/grpcx/hook.go","lineNumber":75,"sourceCode":"\n\t\t\t\tname, opts := hooks.Decode(opts[0])\n\t\t\t\tgrpcHook := hookRegistry[name](opts)\n\t\t\t\tif grpcHook.Dialer != nil {\n\t\t\t\t\tDial = grpcHook.Dialer\n\t\t\t\t}\n\t\t\t\treturn ctx, nil\n\t\t\t},\n\t\t}\n\t}\n\thooks.RegisterHook(\"grpc\", hf)\n}\n\n// EnableHook is called to request the use of the gRPC\n// hook in a pipeline.\nfunc EnableHook(name string, opts ...string) {\n\t_, exists := hookRegistry[name]\n\tif !exists {\n\t\tpanic(fmt.Sprintf(\"EnableHook: %s not registered\", name))\n\t}\n\t// Only one hook can be enabled. If the pipeline has two conflicting views about how to use gRPC\n\t// that won't end well.\n\tif exists, opts := hooks.IsEnabled(\"grpc\"); exists {\n\t\tn, _ := hooks.Decode(opts[0])\n\t\tif n != name {\n\t\t\tpanic(fmt.Sprintf(\"EnableHook: can't enable hook %s, hook %s already enabled\", name, n))\n\t\t}\n\t}\n\n\thooks.EnableHook(\"grpc\", hooks.Encode(name, opts))\n}\n","sourceCodeStart":57,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/util/grpcx/hook.go#L57-L88","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Import the package that registers the hook (side-effect import: _ \"path/to/hook\") so its init() runs","Verify the hook name string matches a registered identifier exactly","Call RegisterHook before EnableHook for custom hooks","Check build tags/files to ensure the registration code is compiled into the binary"],"exampleFix":"// before\nfunc main() {\n\tgrpcx.EnableHook(\"custom-hook\") // panics: not registered\n}\n// after\nimport _ \"example.com/beam/hooks/custom\"\nfunc main() {\n\tgrpcx.EnableHook(\"custom-hook\")\n}","handlingStrategy":"try-catch","validationCode":"if !hookIsRegistered(name) {\n\treturn fmt.Errorf(\"hook %q must be registered before EnableHook\", name)\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\terr = fmt.Errorf(\"EnableHook failed: %v\", r)\n\t}\n}()","preventionTips":["Side-effect import the hook package so init() registration runs","Keep hook name strings as constants shared with registration code","Verify build tags don't exclude registration files"],"tags":["go","grpc","panic","initialization"],"backgroundTag":"resource-not-found","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}