{"record":{"id":"19377472dc69bd88","repo":"wavetermdev/waveterm","slug":"authentication-returned-empty-routeid","errorCode":null,"errorMessage":"authentication returned empty routeid","messagePattern":"authentication returned empty routeid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/waveapp/waveapp.go","lineNumber":189,"sourceCode":"\tif client.RpcContext == nil || client.RpcContext.BlockId == \"\" {\n\t\treturn fmt.Errorf(\"no block id in rpc context\")\n\t}\n\tclient.ServerImpl = &WaveAppServerImpl{BlockId: client.RpcContext.BlockId, Client: client}\n\tsockName, err := wshutil.ExtractUnverifiedSocketName(jwtToken)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error extracting socket name from %s: %v\", wshutil.WaveJwtTokenVarName, err)\n\t}\n\trpcClient, err := wshutil.SetupDomainSocketRpcClient(sockName, client.ServerImpl, \"vdomclient\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error setting up domain socket rpc client: %v\", err)\n\t}\n\tclient.RpcClient = rpcClient\n\tauthRtnData, err := wshclient.AuthenticateCommand(client.RpcClient, jwtToken, &wshrpc.RpcOpts{Route: wshutil.ControlRoute})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error authenticating rpc connection: %v\", err)\n\t}\n\tif authRtnData.RouteId == \"\" {\n\t\treturn fmt.Errorf(\"authentication returned empty routeid\")\n\t}\n\tclient.RouteId = authRtnData.RouteId\n\treturn nil\n}\n\nfunc (c *Client) SetRootElem(elem *vdom.VDomElem) {\n\tc.RootElem = elem\n}\n\nfunc (c *Client) CreateVDomContext(target *vdom.VDomTarget) error {\n\tblockORef, err := wshclient.VDomCreateContextCommand(\n\t\tc.RpcClient,\n\t\tvdom.VDomCreateContext{Target: target},\n\t\t&wshrpc.RpcOpts{Route: wshutil.MakeFeBlockRouteId(c.RpcContext.BlockId)},\n\t)\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/waveapp/waveapp.go#L171-L207","documentation":"AuthenticateCommand succeeded at the transport level but returned an AuthRtnData with an empty RouteId. Wave assigns each authenticated client a route id used to address events and RPCs back to it; an empty RouteId means the server's response was incomplete or from an incompatible server version. Connect treats this as fatal because the client cannot register its route.","triggerScenarios":"Calling Connect against a Wave Terminal version whose AuthenticateCommand response lacks RouteId, a server bug returning a zero-value response, or a decoding issue where the response fields were dropped.","commonSituations":"Mixing a new waveapp binary with an older Wave Terminal (or vice versa) so response schemas differ; custom/proxy RPC intermediaries stripping response fields.","solutions":["Upgrade Wave Terminal and the waveapp to matching versions.","Re-run Connect; if transient, a retry may return a populated RouteId.","Log the full authRtnData response to confirm which fields came back.","Check for a proxy or shim intercepting the control route."],"exampleFix":"// before\nif authRtnData.RouteId == \"\" { return fmt.Errorf(\"authentication returned empty routeid\") }\n// after: add diagnostics before failing\nif authRtnData.RouteId == \"\" {\n    log.Printf(\"auth response: %+v\", authRtnData)\n    return fmt.Errorf(\"authentication returned empty routeid (wave version mismatch?)\")\n}","handlingStrategy":"validation","validationCode":"if authRtnData == nil || authRtnData.RouteId == \"\" {\n    return fmt.Errorf(\"authentication returned no route id; check Wave/waveapp version match\")\n}","typeGuard":"func hasRouteId(d *wshrpc.AuthRtnData) bool {\n    return d != nil && d.RouteId != \"\"\n}","tryCatchPattern":"authRtnData, err := wshclient.AuthenticateCommand(client.RpcClient, jwtToken, &wshrpc.RpcOpts{Route: wshutil.ControlRoute})\nif err != nil {\n    return fmt.Errorf(\"error authenticating rpc connection: %v\", err)\n}\nif !hasRouteId(authRtnData) {\n    return fmt.Errorf(\"authentication returned empty routeid\")\n}","preventionTips":["Keep Wave Terminal and the waveapp SDK on compatible versions.","Log the full auth response when RouteId is empty to aid debugging.","Retry once — a transient server hiccup can produce an empty response.","Avoid intermediaries/proxies on the control route."],"tags":["authentication","rpc","version-compatibility"],"backgroundTag":"empty-rpc-response","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}