{"record":{"id":"5c8e775738200be5","repo":"wavetermdev/waveterm","slug":"no-route-for-q","errorCode":null,"errorMessage":"no route for %q","messagePattern":"no route for %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshrouter.go","lineNumber":196,"sourceCode":"\nfunc (router *WshRouter) SetAsRootRouter() {\n\trouter.lock.Lock()\n\tdefer router.lock.Unlock()\n\trouter.isRootRouter = true\n\n\t// also bind $control:root to the control RPC\n\tlinkId := router.routeMap[ControlRoute]\n\tif linkId != baseds.NoLinkId {\n\t\trouter.routeMap[ControlRootRoute] = linkId\n\t\tlog.Printf(\"wshrouter registered control:root route linkid=%d\", linkId)\n\t}\n}\n\nfunc noRouteErr(routeId string) error {\n\tif routeId == \"\" {\n\t\treturn errors.New(\"no default route\")\n\t}\n\treturn fmt.Errorf(\"no route for %q\", routeId)\n}\n\nfunc (router *WshRouter) SendEvent(routeId string, event wps.WaveEvent) {\n\tdefer func() {\n\t\tpanichandler.PanicHandler(\"WshRouter.SendEvent\", recover())\n\t}()\n\tlm := router.getLinkForRoute(routeId)\n\tif lm == nil {\n\t\treturn\n\t}\n\tmsg := RpcMessage{\n\t\tCommand: wshrpc.Command_EventRecv,\n\t\tRoute:   routeId,\n\t\tData:    event,\n\t}\n\tmsgBytes, err := json.Marshal(msg)\n\tif err != nil {\n\t\t// nothing to do","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshrouter.go#L178-L214","documentation":"WshRouter routes RPCs and events by routeId. noRouteErr produces this error when a message arrives (or is sent) for a routeId that has no registered route and no default route is configured; an empty routeId yields the plainer \"no default route\" error. It indicates the wsh message could not be delivered to any handler.","triggerScenarios":"Sending an RPC/event with SendRpcRequest/SendEvent to a routeId that was never registered (RegisterRoute) or was already unregistered (UnregisterRoute); specifying a route before the remote side finished setting up its routes; a typo in a RouteId.","commonSituations":"Calling a server command before the websocket/controller connection is established so the route is not yet registered; a remote block/terminal closed so its route disappeared; hand-writing route strings instead of using wshrpc.RouteId_* constants; race between route registration and the first RPC after connection.","solutions":["Verify the routeId against the wshrpc.RouteId_* constants and fix typos.","Ensure the remote side has registered the route before sending — wait for connection/route-ready (e.g. retry after registering controllers), or use the default controller route for general commands.","Check that the target block/route still exists (the block may have been closed, unregistering its route); reacquire a valid routeId.","If routing to your own endpoint, call router.RegisterRoute(routeId, processor) before sending traffic to it."],"exampleFix":"// before: guessing a route id\nclient.SendRpcRequest(ctx, \"routeservice\", req) // no route for \"routeservice\"\n// after: use the declared constant / register first\nerr := client.SendRpcRequest(ctx, wshrpc.RouteId_Controller, req)\n// or, for a custom endpoint:\nrouter.RegisterRoute(\"routeservice\", myProcessor)\nerr := client.SendRpcRequest(ctx, \"routeservice\", req)","handlingStrategy":"retry","validationCode":"// Confirm the route is registered before sending:\nif !routerHasRoute(routeId) {\n    return fmt.Errorf(\"route %s not yet registered; wait for connection\", routeId)\n}","typeGuard":null,"tryCatchPattern":"err := client.SendRpcRequest(ctx, routeId, req)\nif err != nil && (strings.Contains(err.Error(), \"no route for\") || strings.Contains(err.Error(), \"no default route\")) {\n    // brief backoff then re-resolve the route and retry once\n    time.Sleep(250 * time.Millisecond)\n    routeId = resolveRoute()\n    return client.SendRpcRequest(ctx, routeId, req)\n}","preventionTips":["Use wshrpc.RouteId_* constants instead of hand-written route strings.","Wait for connection/route-ready signals before issuing the first RPC.","Handle closed blocks/routes: re-resolve routeIds instead of caching them indefinitely.","Register custom routes (RegisterRoute) before sending traffic to them."],"tags":["rpc","wsh","routing","waveterm"],"backgroundTag":"no-route-for-id","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}