{"record":{"id":"14373dcb58632aaf","repo":"GoogleContainerTools/skaffold","slug":"no-receiver-was-registered","errorCode":null,"errorMessage":"no receiver was registered","messagePattern":"no receiver was registered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/kubernetes/watcher.go","lineNumber":72,"sourceCode":"\t\treceivers:   make(map[chan<- PodEvent]bool),\n\t}\n}\n\nfunc (w *podWatcher) Register(receiver chan<- PodEvent) {\n\tw.receiverLock.Lock()\n\tw.receivers[receiver] = true\n\tw.receiverLock.Unlock()\n}\n\nfunc (w *podWatcher) Deregister(receiver chan<- PodEvent) {\n\tw.receiverLock.Lock()\n\tw.receivers[receiver] = false\n\tw.receiverLock.Unlock()\n}\n\nfunc (w *podWatcher) Start(ctx context.Context, kubeContext string, namespaces []string) (func(), error) {\n\tif len(w.receivers) == 0 {\n\t\treturn func() {}, errors.New(\"no receiver was registered\")\n\t}\n\n\tvar watchers []watch.Interface\n\tstopWatchers := func() {\n\t\tfor _, w := range watchers {\n\t\t\tw.Stop()\n\t\t}\n\t}\n\n\tkubeclient, err := client.Client(kubeContext)\n\tif err != nil {\n\t\treturn func() {}, fmt.Errorf(\"getting k8s client: %w\", err)\n\t}\n\n\tvar forever int64 = 3600 * 24 * 365 * 100\n\n\tfor _, ns := range namespaces {\n\t\twatcher, err := kubeclient.CoreV1().Pods(ns).Watch(context.Background(), metav1.ListOptions{","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/kubernetes/watcher.go#L54-L90","documentation":"podWatcher.Start requires at least one receiver registered before it begins watching pods. Calling Start with zero registered receivers returns this error immediately, because watch events would have nowhere to be delivered.","triggerScenarios":"Calling podWatcher.Start(ctx, kubeContext, namespaces) before any call to AddReceiver (or after all receivers were removed).","commonSituations":"Race in startup code where the watch is started before the status-check receiver is registered; a refactor removing AddReceiver calls; conditional code path that skips receiver registration.","solutions":["Register at least one receiver with podWatcher.AddReceiver before calling Start","Reorder startup so receiver registration happens before the watcher starts","Guard the call site: only start the watcher when the receiver list is non-empty"],"exampleFix":"// before\nwatcher.Start(ctx, kubeContext, namespaces) // error: no receiver was registered\n// after\nwatcher.AddReceiver(receiver)\nwatcher.Start(ctx, kubeContext, namespaces)","handlingStrategy":"validation","validationCode":"if len(watcher.ReceiverCount()) == 0 { return errors.New(\"refusing to start podWatcher with no receivers\") }\nif err := watcher.Start(ctx, kubeContext, namespaces); err != nil { return err }","typeGuard":"func (w *podWatcher) HasReceivers() bool { return len(w.receivers) > 0 }","tryCatchPattern":"stop, err := watcher.Start(ctx, kubeContext, ns)\nif err != nil {\n  if strings.Contains(err.Error(), \"no receiver was registered\") { return fmt.Errorf(\"watcher startup ordering bug: %w\", err) }\n  return err\n}\ndefer stop()","preventionTips":["Always call AddReceiver before Start in setup code","Centralize watcher bootstrapping in one function to fix ordering","Assert receiver registration in tests before exercising Start"],"tags":["kubernetes","watcher","skaffold"],"backgroundTag":"no-receiver-registered","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}