{"record":{"id":"9257071a48c4702a","repo":"wavetermdev/waveterm","slug":"no-route-id-available-925707","errorCode":null,"errorMessage":"no route id available","messagePattern":"no route id available","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/fileshare/wshfs/wshfs.go","lineNumber":57,"sourceCode":"\t}\n\treturn conn, nil\n}\n\nfunc Read(ctx context.Context, data wshrpc.FileData) (*wshrpc.FileData, error) {\n\tif data.Info == nil {\n\t\treturn nil, fmt.Errorf(\"file info is required\")\n\t}\n\tlog.Printf(\"Read: %v\", data.Info.Path)\n\tconn, err := parseConnection(ctx, data.Info.Path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tbroker := RpcClient.StreamBroker\n\tif broker == nil {\n\t\treturn nil, fmt.Errorf(\"stream broker not available\")\n\t}\n\tif RpcClientRouteId == \"\" {\n\t\treturn nil, fmt.Errorf(\"no route id available\")\n\t}\n\treaderRouteId := RpcClientRouteId\n\twriterRouteId := wshutil.MakeConnectionRouteId(conn.Host)\n\treader, streamMeta := broker.CreateStreamReader(readerRouteId, writerRouteId, 256*1024)\n\tdefer reader.Close()\n\tgo func() {\n\t\t<-ctx.Done()\n\t\treader.Close()\n\t}()\n\tbyteRange := \"\"\n\tif data.At != nil && data.At.Size > 0 {\n\t\tbyteRange = fmt.Sprintf(\"%d-%d\", data.At.Offset, data.At.Offset+int64(data.At.Size)-1)\n\t}\n\tremoteData := wshrpc.CommandRemoteFileStreamData{\n\t\tPath:       conn.Path,\n\t\tByteRange:  byteRange,\n\t\tStreamMeta: *streamMeta,\n\t}","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/remote/fileshare/wshfs/wshfs.go#L39-L75","documentation":"Read needs the package-level RpcClientRouteId to know which route the local stream reader listens on. If it is empty, the client was never assigned a route id during initialization, and Read refuses to build the stream. Like RpcClient, this global must be set by whoever initializes the client (main-server or wshcmd-connserver).","triggerScenarios":"Calling wshfs.Read when wshfs.RpcClientRouteId is still \"\" — i.e. the embedding binary never called the route-id registration that populates it, or Read runs before that registration.","commonSituations":"Custom tool linking wshfs without performing the wsh router registration; race where a request arrives during startup before route assignment; recent refactor dropped the SetRouteId call.","solutions":["Set wshfs.RpcClientRouteId (via the wshutil route registration for the RPC client) during startup before serving file commands","Log the route id at startup to confirm it is populated","Guard/queue file operations until initialization completes"],"exampleFix":"// before\nwshfs.RpcClient = rpc // route id never assigned\n// after\nwshfs.RpcClient = rpc\nwshfs.RpcClientRouteId = wshutil.SetupRouterKit(rpc) // assign route before use","handlingStrategy":"validation","validationCode":"if wshfs.RpcClientRouteId == \"\" {\n    return errors.New(\"wshfs route id not initialized; set RpcClientRouteId during setup\")\n}","typeGuard":"func routeReady() bool {\n    return wshfs.RpcClientRouteId != \"\"\n}","tryCatchPattern":"out, err := wshfs.Read(ctx, data)\nif err != nil {\n    if strings.Contains(err.Error(), \"no route id available\") {\n        return fmt.Errorf(\"initialization incomplete (route id empty): %w\", err)\n    }\n    return err\n}","preventionTips":["Assign RpcClientRouteId immediately after creating/registering the RPC client","Gate request handling behind an init-done flag so requests cannot arrive early","Log the route id at startup for diagnosability","Keep route setup in one shared initializer used by all entry points"],"tags":["go","initialization","routing"],"backgroundTag":"missing-route-id","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}