wavetermdev/waveterm · error
no source in routeannounce
Error message
no source in routeannounce
What it means
RouteAnnounceCommand is the control-protocol handler for 'routeannounce' messages arriving on a router's control channel. The originating source route id is read from the RPC context via GetRpcSourceFromContext; announce handling needs to know which link announced the route, so if the context carries no source, the command is rejected. This indicates the announce was dispatched without proper routing context rather than a normal runtime condition.
Source
Thrown at pkg/wshutil/wshrouter_controlimpl.go:28
"github.com/wavetermdev/waveterm/pkg/baseds"
"github.com/wavetermdev/waveterm/pkg/util/shellutil"
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
"github.com/wavetermdev/waveterm/pkg/waveobj"
"github.com/wavetermdev/waveterm/pkg/wshrpc"
"github.com/wavetermdev/waveterm/pkg/wstore"
)
type WshRouterControlImpl struct {
Router *WshRouter
}
func (impl *WshRouterControlImpl) WshServerImpl() {}
func (impl *WshRouterControlImpl) RouteAnnounceCommand(ctx context.Context) error {
source := GetRpcSourceFromContext(ctx)
if source == "" {
return fmt.Errorf("no source in routeannounce")
}
handler := GetRpcResponseHandlerFromContext(ctx)
if handler == nil {
return fmt.Errorf("no response handler in context")
}
linkId := handler.GetIngressLinkId()
if linkId == baseds.NoLinkId {
return fmt.Errorf("no ingress link found")
}
return impl.Router.bindRoute(linkId, source, false)
}
func (impl *WshRouterControlImpl) RouteUnannounceCommand(ctx context.Context) error {
source := GetRpcSourceFromContext(ctx)
if source == "" {
return fmt.Errorf("no source in routeunannounce")
}
handler := GetRpcResponseHandlerFromContext(ctx)View on GitHub (pinned to a4447c1563)
Solutions
- Ensure the sending side has its source route bound (bindRouteLocally with isSourceRoute=true) before emitting routeannounce, so the context carries the source
- Send routeannounce through the normal WshRouter/WshClient control path rather than constructing the RPC context manually
- Check that GetRpcResponseHandlerFromContext / ingress link setup ran for the connection before the announce is dispatched
Example fix
// before
ctx := context.Background()
err := wshclient.RouteAnnounceCommand(ctx, client) // no source in ctx
// after
ctx = context.WithValue(context.Background(), RpcSourceKey{}, sourceRouteId)
err = wshclient.RouteAnnounceCommand(ctx, client) Defensive patterns
Strategy: try-catch
Validate before calling
source := wshutil.GetRpcSourceFromContext(ctx)
if source == "" {
return fmt.Errorf("cannot announce: no source route bound")
}
err := wshclient.RouteAnnounceCommand(ctx, client) Type guard
func hasRpcSource(ctx context.Context) bool {
return wshutil.GetRpcSourceFromContext(ctx) != ""
}
if !hasRpcSource(ctx) { return } Try / catch
err := wshclient.RouteAnnounceCommand(ctx, client)
if err != nil && strings.Contains(err.Error(), "no source in routeannounce") {
// the ingress link's source route was never bound; bind it before announcing
} Prevention
- Always bind the sender's source route before sending routeannounce control messages
- Use wshclient/rpc helper paths instead of hand-constructing RPC contexts
- Verify ingress link setup (response handler, ingress link id) on every new connection before control traffic
When it happens
Trigger: A routeannounce control message processed through a code path that did not set the RPC source in the context (missing source-route binding on the ingress link, or a hand-built context without the source annotation).
Common situations: Sending raw routeannounce control messages over a connection without the router having bound the sender's source route; custom/protocol-level clients speaking wsh control protocol without setting up context metadata; a router regression where ingress link id / source context is lost before the control impl runs.
Related errors
- invalid routeid %q
- cannot unbind %q to NoLinkId
- cannot bindroute %q to NoLinkId
- router cannot register %q route (invalid routeid)
- cannot bind route %q, no link with id %d found
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/0ce0ac2d93bdc6e4.
Report an issue: GitHub.