{"record":{"id":"b7f4bb41e5f1a57e","repo":"wavetermdev/waveterm","slug":"error-copying-file-q-to-q-w","errorCode":null,"errorMessage":"error copying file %q to %q: %w","messagePattern":"error copying file %q to %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshremote/wshremote_file.go","lineNumber":190,"sourceCode":"\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() {\n\t\tdefer func() {\n\t\t\tpanichandler.PanicHandler(\"RemoteListEntriesCommand\", recover())\n\t\t}()","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshremote/wshremote_file.go#L172-L208","documentation":"RemoteFileCopyCommand wraps any error returned by io.Copy(destFile, reader), which transfers bytes from the remote read stream into the destination file. This means the stream started successfully but data transfer failed mid-copy (network interruption, read/write I/O error).","triggerScenarios":"io.Copy fails during RemoteFileCopyCommand: the read side (remote stream) errors out, the destination write fails (disk full, permission), or the RPC stream breaks while transferring.","commonSituations":"Large file transfer over a flaky SSH/network connection; destination disk quota exceeded; destination directory became unwritable after the copy began.","solutions":["Check the wrapped error for network vs. local I/O causes.","Verify destination disk space and write permissions.","Re-run the copy; consider deleting a partial destination file first.","For large/unstable transfers, ensure the connection is stable or use a resumable approach."],"exampleFix":"// before\n_, err := wshclient.RemoteFileCopyCommand(ctx, copyData, nil)\n// after\nerr := wshclient.RemoteFileCopyCommand(ctx, copyData, nil)\nif err != nil && strings.Contains(err.Error(), \"error copying file\") {\n    _ = os.Remove(destPath) // clean partial file\n    err = wshclient.RemoteFileCopyCommand(ctx, copyData, nil)\n}","handlingStrategy":"retry","validationCode":"info, err := wshclient.RemoteFileInfoCommand(ctx, srcUri, nil)\nif err != nil { return err }\n// check dest has enough space if size known\n_ = info.Size","typeGuard":null,"tryCatchPattern":"for attempt := 0; attempt < 3; attempt++ {\n    err := wshclient.RemoteFileCopyCommand(ctx, data, nil)\n    if err == nil { break }\n    if strings.Contains(err.Error(), \"error copying file\") {\n        _ = os.Remove(destPath); time.Sleep(backoff(attempt)); continue\n    }\n    return err\n}","preventionTips":["Remove partial destination files after failed copies","Monitor network stability for large transfers","Check destination free space before copying"],"tags":["io","file-copy","stream","network"],"backgroundTag":"file-copy-io-error","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}