ethereum/go-ethereum · error

Notify with wrong ID

Error message

Notify with wrong ID

What it means

Notifier.Notify panics when the ID argument does not equal the ID of the subscription created on this Notifier. Each Notifier is bound to exactly one subscription, so an ID mismatch means the caller is trying to route a notification for a different subscription through the wrong Notifier.

Source

Thrown at rpc/subscription.go:139

	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
}

// activate is called after the subscription ID was sent to client. Notifications are

View on GitHub (pinned to 6bb0588ad8)

Solutions

  1. Always use the ID from the subscription created on the same Notifier: sub := notifier.CreateSubscription(); notifier.Notify(sub.ID, data).
  2. Keep a map from your internal event source to the owning (*Notifier, *Subscription) pair to avoid cross-routing.
  3. Treat subscription IDs as opaque and connection-scoped; never recycle them across sessions.

Example fix

// before
notifierA.Notify(subB.ID, payload) // subB created via notifierB -> panic

// after
notifierA.Notify(subA.ID, payload)
Defensive patterns

Strategy: validation

Validate before calling

if id != sub.ID {
    return fmt.Errorf("notifier can only deliver for its own subscription, got %v want %v", id, sub.ID)
}
notifier.Notify(id, data)

Prevention

When it happens

Trigger: Calling notifier.Notify(otherSub.ID, data) where otherSub was created by a different Notifier/method call; copying a Notify example but passing a hard-coded or client-side subscription ID.

Common situations: Services managing multiple subscriptions and mixing up which Notifier belongs to which; persisting subscription IDs and reusing them after reconnect (IDs are connection-scoped); concurrent subscribe calls where IDs get crossed.

Related errors


AI-assisted analysis of ethereum/go-ethereum@6bb0588ad8 (2026-08-15). Data as JSON: /api/errors/85e050328ddb366c. Report an issue: GitHub.