{"record":{"id":"5bcb73f8636bb1c2","repo":"wavetermdev/waveterm","slug":"error-starting-file-stream-for-q-w","errorCode":null,"errorMessage":"error starting file stream for %q: %w","messagePattern":"error starting file stream for %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshremote/wshremote_file.go","lineNumber":187,"sourceCode":"\tdefer destFile.Close()\n\n\tif wshfs.RpcClientRouteId == \"\" {\n\t\treturn false, fmt.Errorf(\"stream broker route id not available for file copy\")\n\t}\n\twriterRouteId := wshutil.MakeConnectionRouteId(srcConn.Host)\n\treader, streamMeta := wshfs.RpcClient.StreamBroker.CreateStreamReader(wshfs.RpcClientRouteId, writerRouteId, 256*1024)\n\tlog.Printf(\"RemoteFileCopyCommand: readroute=%s writeroute=%s\", streamMeta.ReaderRouteId, streamMeta.WriterRouteId)\n\tdefer reader.Close()\n\tgo func() {\n\t\t<-readCtx.Done()\n\t\treader.Close()\n\t}()\n\tstreamData := wshrpc.CommandRemoteFileStreamData{\n\t\tPath:       srcConn.Path,\n\t\tStreamMeta: *streamMeta,\n\t}\n\tif _, err = wshclient.RemoteFileStreamCommand(wshfs.RpcClient, streamData, &wshrpc.RpcOpts{Route: writerRouteId}); err != nil {\n\t\treturn false, fmt.Errorf(\"error starting file stream for %q: %w\", data.SrcUri, err)\n\t}\n\tif _, err = io.Copy(destFile, reader); err != nil {\n\t\treturn false, fmt.Errorf(\"error copying file %q to %q: %w\", data.SrcUri, data.DestUri, err)\n\t}\n\n\ttotalTime := time.Since(copyStart).Seconds()\n\ttotalMegaBytes := float64(srcFileInfo.Size) / 1024 / 1024\n\trate := float64(0)\n\tif totalTime > 0 {\n\t\trate = totalMegaBytes / totalTime\n\t}\n\tlog.Printf(\"RemoteFileCopyCommand: done; 1 file copied in %.3fs, total of %.4f MB, %.2f MB/s\\n\", totalTime, totalMegaBytes, rate)\n\treturn false, nil\n}\n\nfunc (impl *ServerImpl) RemoteListEntriesCommand(ctx context.Context, data wshrpc.CommandRemoteListEntriesData) chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteListEntriesRtnData] {\n\tch := make(chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteListEntriesRtnData], 16)\n\tgo func() {","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshremote/wshremote_file.go#L169-L205","documentation":"RemoteFileCopyCommand in wshremote wraps the failure of the initial RemoteFileStreamCommand RPC call that opens the read stream on the source connection. This wrapper error is raised when the writer-side stream could not be started, so the copy aborts before any bytes are transferred. The underlying cause is always in the wrapped error (auth, route, or stream-open failure).","triggerScenarios":"Calling RemoteFileCopyCommand where wshclient.RemoteFileStreamCommand (routed to writerRouteId) returns an error, e.g. the source file does not exist, RPC routing fails, or the remote peer rejects the stream request.","commonSituations":"Copying a file whose source path was deleted between listing and copy; stale or invalid writer route id; remote connection dropped mid-copy setup; permission denied on the source file.","solutions":["Inspect the wrapped cause (%w) to identify whether it is file-not-found, permission, or RPC routing.","Verify the source URI exists via RemoteFileInfoCommand before copying.","Check that the remote connection is alive and the writerRouteId is valid/registered.","Retry the copy after re-establishing the connection."],"exampleFix":"// before\n_, err := wshclient.RemoteFileCopyCommand(ctx, copyData, nil)\n// after\ninfo, err := wshclient.RemoteFileInfoCommand(ctx, srcUri, nil)\nif err != nil {\n    return fmt.Errorf(\"source missing, aborting copy: %w\", err)\n}\n_, err = wshclient.RemoteFileCopyCommand(ctx, copyData, nil)","handlingStrategy":"try-catch","validationCode":"if _, err := wshclient.RemoteFileInfoCommand(ctx, srcUri, nil); err != nil {\n    return fmt.Errorf(\"source unavailable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := wshclient.RemoteFileCopyCommand(ctx, data, nil)\nvar startErr error\nif err != nil && strings.Contains(err.Error(), \"error starting file stream\") {\n    startErr = err // wrapped cause: check connection/route, then retry\n}","preventionTips":["Verify source file exists before copying","Keep connections alive and re-dial before long copies","Log the wrapped cause, not just the wrapper"],"tags":["rpc","file-copy","stream","remote"],"backgroundTag":"rpc-stream-start-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}