GoogleContainerTools/skaffold · error
no receiver was registered
Error message
no receiver was registered
What it means
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.
Source
Thrown at pkg/skaffold/kubernetes/watcher.go:72
receivers: make(map[chan<- PodEvent]bool),
}
}
func (w *podWatcher) Register(receiver chan<- PodEvent) {
w.receiverLock.Lock()
w.receivers[receiver] = true
w.receiverLock.Unlock()
}
func (w *podWatcher) Deregister(receiver chan<- PodEvent) {
w.receiverLock.Lock()
w.receivers[receiver] = false
w.receiverLock.Unlock()
}
func (w *podWatcher) Start(ctx context.Context, kubeContext string, namespaces []string) (func(), error) {
if len(w.receivers) == 0 {
return func() {}, errors.New("no receiver was registered")
}
var watchers []watch.Interface
stopWatchers := func() {
for _, w := range watchers {
w.Stop()
}
}
kubeclient, err := client.Client(kubeContext)
if err != nil {
return func() {}, fmt.Errorf("getting k8s client: %w", err)
}
var forever int64 = 3600 * 24 * 365 * 100
for _, ns := range namespaces {
watcher, err := kubeclient.CoreV1().Pods(ns).Watch(context.Background(), metav1.ListOptions{View on GitHub (pinned to a1189de023)
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
Example fix
// before watcher.Start(ctx, kubeContext, namespaces) // error: no receiver was registered // after watcher.AddReceiver(receiver) watcher.Start(ctx, kubeContext, namespaces)
Defensive patterns
Strategy: validation
Validate before calling
if len(watcher.ReceiverCount()) == 0 { return errors.New("refusing to start podWatcher with no receivers") }
if err := watcher.Start(ctx, kubeContext, namespaces); err != nil { return err } Type guard
func (w *podWatcher) HasReceivers() bool { return len(w.receivers) > 0 } Try / catch
stop, err := watcher.Start(ctx, kubeContext, ns)
if err != nil {
if strings.Contains(err.Error(), "no receiver was registered") { return fmt.Errorf("watcher startup ordering bug: %w", err) }
return err
}
defer stop() Prevention
- 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
When it happens
Trigger: Calling podWatcher.Start(ctx, kubeContext, namespaces) before any call to AddReceiver (or after all receivers were removed).
Common situations: 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.
Related errors
- c.Message (pod status condition message)
- unable to lookup minikube executable. Please add it to PATH
- rs.ae.Message (actionable error message from status check)
- no valid Kubernetes objects decoded
- cannot resolve active Kubernetes context - multiple contexts
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/14373dcb58632aaf.
Report an issue: GitHub.