{"record":{"id":"5c7aaa6debfdb027","repo":"wavetermdev/waveterm","slug":"cannot-bind-route-q-no-link-with-id-d-found","errorCode":null,"errorMessage":"cannot bind route %q, no link with id %d found","messagePattern":"cannot bind route %q, no link with id (.+?) found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshrouter.go","lineNumber":778,"sourceCode":"\trouter.unannounceUpstream(routeId)\n\tif router.IsRootRouter() {\n\t\trouter.unsubscribeFromBroker(routeId)\n\t}\n\treturn nil\n}\n\nfunc (router *WshRouter) bindRouteLocally(linkId baseds.LinkId, routeId string, isSourceRoute bool) error {\n\tif linkId == baseds.NoLinkId {\n\t\treturn fmt.Errorf(\"cannot bindroute %q to NoLinkId\", routeId)\n\t}\n\tif !isBindableRouteId(routeId) {\n\t\treturn fmt.Errorf(\"router cannot register %q route (invalid routeid)\", routeId)\n\t}\n\trouter.lock.Lock()\n\tdefer router.lock.Unlock()\n\tlm := router.linkMap[linkId]\n\tif lm == nil {\n\t\treturn fmt.Errorf(\"cannot bind route %q, no link with id %d found\", routeId, linkId)\n\t}\n\tif !lm.trusted {\n\t\treturn fmt.Errorf(\"cannot bind route %q, link %d is not trusted\", routeId, linkId)\n\t}\n\tif isSourceRoute {\n\t\tif lm.linkKind != LinkKind_Leaf {\n\t\t\treturn fmt.Errorf(\"cannot bind source route %q to link %d (link is not a leaf)\", routeId, linkId)\n\t\t}\n\t\tif lm.sourceRouteId != \"\" && lm.sourceRouteId != routeId {\n\t\t\treturn fmt.Errorf(\"cannot bind source route %q to link %d (link already has source route %q)\", routeId, linkId, lm.sourceRouteId)\n\t\t}\n\t\tlm.sourceRouteId = routeId\n\t} else {\n\t\tif lm.linkKind != LinkKind_Router {\n\t\t\treturn fmt.Errorf(\"cannot bind route %q to link %d (link is not a router)\", routeId, linkId)\n\t\t}\n\t}\n\trouter.routeMap[routeId] = linkId","sourceCodeStart":760,"sourceCodeEnd":796,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshrouter.go#L760-L796","documentation":"After validating routeId, bindRouteLocally looks up the link in router.linkMap. If no link with the given linkId has been registered on this router, the bind cannot proceed because there is no connection to associate the route with. This is the router's 'unknown link' check.","triggerScenarios":"Calling WshRouter.bindRoute with a linkId that was never registered via RegisterUntrustedLink/RegisterRouterLink/RegisterTrustedLeaf, or that was already removed by UnregisterLink.","commonSituations":"Binding a route after the connection dropped and UnregisterLink ran; using a linkId from a different WshRouter instance; reusing a stale cached linkId across a reconnect; race between route binding and concurrent link unregistration.","solutions":["Re-register the link (RegisterUntrustedLink/RegisterRouterLink) and use the freshly returned linkId","Ensure the bind happens while the link is still live; reorder so bind occurs before any unregister/teardown","Use the same WshRouter instance that owns the link; don't pass link ids across router instances"],"exampleFix":"// before\nerr := router.bindRoute(oldLinkId, routeId, true) // oldLinkId unregistered after reconnect\n// after\nlinkId := router.RegisterUntrustedLink(rpc)\nerr := router.bindRoute(linkId, routeId, true)","handlingStrategy":"validation","validationCode":"// bind only with a linkId this router returned and has not unregistered\nlinkId := router.RegisterUntrustedLink(rpc)\nerr := router.bindRoute(linkId, routeId, true)","typeGuard":null,"tryCatchPattern":"err := router.bindRoute(staleLinkId, routeId, isSource)\nif err != nil && strings.Contains(err.Error(), \"no link with id\") {\n    // link was unregistered; re-register the link and retry the bind\n}","preventionTips":["Always bind routes immediately after registering the link, using the returned id","On reconnect, discard old linkIds and rebind with new ones","Don't share linkIds across WshRouter instances"],"tags":["go","wshrouter","routing","unknown-link"],"backgroundTag":"unknown-link-id","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}