{"record":{"id":"3288208e43ddad25","repo":"wavetermdev/waveterm","slug":"authenticatetokenverify-can-only-be-called-on-root","errorCode":null,"errorMessage":"authenticatetokenverify can only be called on root router","messagePattern":"authenticatetokenverify can only be called on root router","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshrouter_controlimpl.go","lineNumber":149,"sourceCode":"\t}\n\tif entry.RpcContext.IsRouter {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"cannot auth router via token\")\n\t}\n\trouteId := entry.RpcContext.GenerateRouteId()\n\tif routeId == \"\" {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no routeid\")\n\t}\n\treturn wshrpc.CommandAuthenticateRtnData{\n\t\tRouteId:        routeId,\n\t\tEnv:            entry.Env,\n\t\tInitScriptText: entry.ScriptText,\n\t\tRpcContext:     entry.RpcContext,\n\t}, nil\n}\n\nfunc (impl *WshRouterControlImpl) AuthenticateTokenVerifyCommand(ctx context.Context, data wshrpc.CommandAuthenticateTokenData) (wshrpc.CommandAuthenticateRtnData, error) {\n\tif !impl.Router.IsRootRouter() {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"authenticatetokenverify can only be called on root router\")\n\t}\n\tif data.Token == \"\" {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no token in authenticatetoken message\")\n\t}\n\n\trtnData, err := extractTokenData(data.Token)\n\tif err != nil {\n\t\tlog.Printf(\"wshrouter authenticate-token-verify error: %v\", err)\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, err\n\t}\n\n\tlog.Printf(\"wshrouter authenticate-token-verify success routeid=%q\", rtnData.RouteId)\n\treturn rtnData, nil\n}\n\nfunc (impl *WshRouterControlImpl) AuthenticateTokenCommand(ctx context.Context, data wshrpc.CommandAuthenticateTokenData) (wshrpc.CommandAuthenticateRtnData, error) {\n\thandler := GetRpcResponseHandlerFromContext(ctx)\n\tif handler == nil {","sourceCodeStart":131,"sourceCodeEnd":167,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshrouter_controlimpl.go#L131-L167","documentation":"AuthenticateTokenVerifyCommand is the root-only control RPC that actually verifies token-swap entries. It refuses to run on any router that is not the root router (IsRootRouter() false), because only the root holds the token-swap store. The call must be routed to the ControlRootRoute so it lands on the root router.","triggerScenarios":"Invoking Command_AuthenticateTokenVerify against a non-root (intermediate/proxy) WshRouter — e.g. an RPC routed to a local router instead of the root control route.","commonSituations":"Custom code calling the verify command directly on a child router/proxy; a chain of routers where the request terminated at an intermediate node rather than the root; misconfigured RpcOpts.Route not set to ControlRootRoute.","solutions":["Route the verify request to the root: pass &wshrpc.RpcOpts{Route: wshutil.ControlRootRoute} in SendRpcRequest.","Prefer calling AuthenticateTokenCommand (the non-verify wrapper) which itself forwards to the root when needed.","Check the router topology — if running inside wsh/ext processes, ensure the control connection reaches the Wave root router."],"exampleFix":"// before\n_, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateTokenVerify, data, nil) // lands on local router\n// after\n_, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateTokenVerify, data, &wshrpc.RpcOpts{Route: wshutil.ControlRootRoute})","handlingStrategy":"validation","validationCode":"if !router.IsRootRouter() {\n    // don't call verify locally; forward to root\n    _, err = wshRpc.SendRpcRequest(ctx, wshrpc.Command_AuthenticateTokenVerify, data, &wshrpc.RpcOpts{Route: wshutil.ControlRootRoute})\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set Route: ControlRootRoute when sending AuthenticateTokenVerify","Prefer the AuthenticateTokenCommand wrapper, which handles root/forwarding automatically","Map your router topology to know which node is the root"],"tags":["auth","rpc","router","routing"],"backgroundTag":"rpc-routed-to-wrong-router","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}