{"record":{"id":"3c7d9ad01e5a4ad8","repo":"wavetermdev/waveterm","slug":"no-wshrpc-in-context","errorCode":null,"errorMessage":"no wshrpc in context","messagePattern":"no wshrpc in context","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshutil/wshrouter_controlimpl.go","lineNumber":191,"sourceCode":"\t}\n\n\tif data.Token == \"\" {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no token in authenticatetoken message\")\n\t}\n\n\tvar rtnData wshrpc.CommandAuthenticateRtnData\n\tvar err error\n\n\tif impl.Router.IsRootRouter() {\n\t\trtnData, err = extractTokenData(data.Token)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"wshrouter authenticate-token error linkid=%d: %v\", linkId, err)\n\t\t\treturn wshrpc.CommandAuthenticateRtnData{}, err\n\t\t}\n\t} else {\n\t\twshRpc := GetWshRpcFromContext(ctx)\n\t\tif wshRpc == nil {\n\t\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no wshrpc in context\")\n\t\t}\n\t\trespData, err := wshRpc.SendRpcRequest(wshrpc.Command_AuthenticateTokenVerify, data, &wshrpc.RpcOpts{Route: ControlRootRoute})\n\t\tif err != nil {\n\t\t\tlog.Printf(\"wshrouter authenticate-token error linkid=%d: failed to verify token: %v\", linkId, err)\n\t\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"failed to verify token: %w\", err)\n\t\t}\n\t\terr = utilfn.ReUnmarshal(&rtnData, respData)\n\t\tif err != nil {\n\t\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"failed to unmarshal response: %w\", err)\n\t\t}\n\t}\n\n\tif rtnData.RpcContext == nil {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no rpccontext in token response\")\n\t}\n\tif rtnData.RouteId == \"\" {\n\t\treturn wshrpc.CommandAuthenticateRtnData{}, fmt.Errorf(\"no routeid in token response\")\n\t}","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshutil/wshrouter_controlimpl.go#L173-L209","documentation":"When AuthenticateTokenCommand runs on a non-root router, it forwards the token to the root via SendRpcRequest using the WshRpc instance taken from the context (GetWshRpcFromContext). This error means the context did not carry a WshRpc, so the router cannot proxy the verification request to the root router.","triggerScenarios":"AuthenticateTokenCommand executing on a non-root router with a context lacking the WshRpc context value — typically a manually constructed context or a dispatch path that did not inject the local WshRpc.","commonSituations":"Custom or test harnesses calling control commands with context.Background(); intermediate router setups where the wshrpc plumbing was not initialized before authentication was attempted; goroutines that detached the original dispatch context.","solutions":["Invoke the command through the normal wshrpc dispatch so GetWshRpcFromContext finds the router's WshRpc instance.","In tests/tools, inject the WshRpc into the context using the wshutil context helper before calling the command.","Ensure router/proxy initialization completes (WshRpc registered) before any token authentication is attempted."],"exampleFix":"// before\nimpl.AuthenticateTokenCommand(context.Background(), data) // no WshRpc -> error\n// after\nctx := wshutil.CtxWithWshRpc(context.Background(), router.GetWshRpc())\nimpl.AuthenticateTokenCommand(ctx, data)","handlingStrategy":"try-catch","validationCode":"// before calling on a non-root router\nif !router.IsRootRouter() && wshutil.GetWshRpcFromContext(ctx) == nil {\n    return fmt.Errorf(\"context lacks WshRpc; initialize router plumbing before token auth\")\n}","typeGuard":"// Go: nil-check narrowing on the rpc\nwshRpc := wshutil.GetWshRpcFromContext(ctx)\nif wshRpc == nil {\n    return fmt.Errorf(\"no wshrpc in context\")\n}","tryCatchPattern":"// Go\nrtn, err := impl.AuthenticateTokenCommand(ctx, data)\nif err != nil && strings.Contains(err.Error(), \"no wshrpc in context\") {\n    return fmt.Errorf(\"router forwarding unavailable; ensure dispatch injected WshRpc: %w\", err)\n}","preventionTips":["Invoke control commands via the standard wshrpc dispatch path","Complete router/proxy initialization before attempting authentication","In tests, inject the WshRpc into the context with wshutil helpers"],"tags":["rpc","context","proxy","auth"],"backgroundTag":"missing-rpc-context-value","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}