ethereum/go-ethereum · error
can't Notify before subscription is created
Error message
can't Notify before subscription is created
What it means
Notifier.Notify panics when no subscription has been created on this Notifier yet. Notify is only valid for delivering data on the subscription obtained from CreateSubscription; calling it before that (or on a fresh Notifier from api.Notifier in a different call) is a programming error.
Source
Thrown at rpc/subscription.go:137
defer n.mu.Unlock()
if n.sub != nil {
panic("can't create multiple subscriptions with Notifier")
} else if n.callReturned {
panic("can't create subscription after subscribe call has returned")
}
n.sub = &Subscription{ID: n.h.idgen(), namespace: n.namespace, err: make(chan error, 1)}
return n.sub
}
// Notify sends a notification to the client with the given data as payload.
// If an error occurs the RPC connection is closed and the error is returned.
func (n *Notifier) Notify(id ID, data any) error {
n.mu.Lock()
defer n.mu.Unlock()
if n.sub == nil {
panic("can't Notify before subscription is created")
} else if n.sub.ID != id {
panic("Notify with wrong ID")
}
if n.activated {
return n.send(n.sub, data)
}
n.buffer = append(n.buffer, data)
return nil
}
// takeSubscription returns the subscription (if one has been created). No subscription can
// be created after this call.
func (n *Notifier) takeSubscription() *Subscription {
n.mu.Lock()
defer n.mu.Unlock()
n.callReturned = true
return n.sub
}View on GitHub (pinned to 6bb0588ad8)
Solutions
- Create the subscription first with CreateSubscription and only Notify with the returned sub.ID afterwards.
- Gate event emission on 'at least one active subscription' state in your service.
- Use the Subscription object's own channel-based delivery if you hold the *Subscription rather than the Notifier.
Example fix
// before notifier.Notify(subID, event) // no CreateSubscription on this notifier -> panic // after sub := notifier.CreateSubscription() notifier.Notify(sub.ID, event)
Defensive patterns
Strategy: validation
Validate before calling
// Only notify through a Notifier you created a subscription on:
if s := notifier.Subscription(); s == nil { // conceptual guard: track creation yourself
return errors.New("no subscription yet")
}
notifier.Notify(sub.ID, data) Prevention
- Pair every Notifier with its Subscription in a small struct so Notify calls always have the counterpart.
- Suppress event emission until the first subscribe request has created a subscription.
- Never call Notify from a fresh api.Notifier(ctx) in a different request.
When it happens
Trigger: Calling notifier.Notify(id, data) without a prior notifier.CreateSubscription() on the same Notifier instance; storing the ID from another session and notifying through a new Notifier.
Common situations: Event-emitting code that runs before the first subscriber calls the subscribe method; passing only the subscription ID around instead of the Subscription object; refactoring where Notify is called from a constructor before the handler created the subscription.
Related errors
- can't create multiple subscriptions with Notifier
- can't create subscription after subscribe call has returned
- Notify with wrong ID
- channel given to Subscribe must not be nil
- nil TextMapPropagator configured
AI-assisted analysis of ethereum/go-ethereum@6bb0588ad8 (2026-08-15).
Data as JSON: /api/errors/023467b47ed2e2a8.
Report an issue: GitHub.