{"record":{"id":"caa4866fc22ea31f","repo":"wavetermdev/waveterm","slug":"cannot-get-info-for-source-file-q-w","errorCode":null,"errorMessage":"cannot get info for source file %q: %w","messagePattern":"cannot get info for source file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshremote/wshremote_file.go","lineNumber":151,"sourceCode":"\n\tif srcConn.Host == destConn.Host {\n\t\tsrcPathCleaned := filepath.Clean(wavebase.ExpandHomeDirSafe(srcConn.Path))\n\t\terr := remoteCopyFileInternal(data.SrcUri, data.DestUri, srcPathCleaned, destPathCleaned, destHasSlash, opts.Overwrite)\n\t\treturn false, err\n\t}\n\n\t// FROM external TO here - only supports single file copying\n\ttimeout := wshfs.DefaultTimeout\n\tif opts.Timeout > 0 {\n\t\ttimeout = time.Duration(opts.Timeout) * time.Millisecond\n\t}\n\treadCtx, timeoutCancel := context.WithTimeoutCause(ctx, timeout, fmt.Errorf(\"timeout copying file %q to %q\", data.SrcUri, data.DestUri))\n\tdefer timeoutCancel()\n\tcopyStart := time.Now()\n\n\tsrcFileInfo, err := wshclient.RemoteFileInfoCommand(wshfs.RpcClient, srcConn.Path, &wshrpc.RpcOpts{Timeout: opts.Timeout, Route: wshutil.MakeConnectionRouteId(srcConn.Host)})\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"cannot get info for source file %q: %w\", data.SrcUri, err)\n\t}\n\tif srcFileInfo.IsDir {\n\t\treturn false, fmt.Errorf(\"copying directories is not supported\")\n\t}\n\tif srcFileInfo.Size > RemoteFileTransferSizeLimit {\n\t\treturn false, fmt.Errorf(\"file %q size %d exceeds transfer limit of %d bytes\", data.SrcUri, srcFileInfo.Size, RemoteFileTransferSizeLimit)\n\t}\n\n\tdestFilePath, err := prepareDestForCopy(destPathCleaned, fspath.Base(srcConn.Path), destHasSlash, opts.Overwrite)\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\tdestFile, err := os.OpenFile(destFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, srcFileInfo.Mode)\n\tif err != nil {\n\t\treturn false, fmt.Errorf(\"cannot create destination file %q: %w\", destFilePath, err)\n\t}\n\tdefer destFile.Close()","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshremote/wshremote_file.go#L133-L169","documentation":"RemoteFileCopyCommand first issues a RemoteFileInfoCommand RPC to the source host to stat the file being copied. This error wraps any failure of that RPC — the file may not exist, be unreadable, the connection may be down, or the RPC may time out. The wrapper adds the source URI (%q) so the caller knows which path failed; the underlying cause is in the wrapped error.","triggerScenarios":"Calling wshclient.RemoteFileInfoCommand for srcConn.Path over route MakeConnectionRouteId(srcConn.Host) returns an error: nonexistent source path, permission denied, source connection offline/not routed, or RPC timeout (opts.Timeout or wshfs.DefaultTimeout elapsed).","commonSituations":"Typo in the source URI; wsh not installed/running on the remote host; SSH connection dropped; copying from a mount (s3:/, wsh://) whose connection is not authenticated; source file deleted between listing and copy.","solutions":["Verify the source URI exists and is readable on the source host (run `wsh ls` or an equivalent RemoteFileInfoCommand call first).","Check the connection to the source host is up and routed (MakeConnectionRouteId(srcConn.Host) resolves to a live wsh client).","Inspect the wrapped cause (%w) to distinguish os.ErrNotExist / permission errors from timeouts and fix accordingly.","Increase opts.Timeout if large/slow hosts cause RPC timeouts."],"exampleFix":"// before\nok, err := RemoteFileCopyCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: \"wsh://host/typo/path.txt\", DestUri: \"/tmp/out\"})\n// after\nif _, err := wshclient.RemoteFileInfoCommand(rpc, path, &wshrpc.RpcOpts{Route: wshutil.MakeConnectionRouteId(host)}); err != nil {\n    log.Fatalf(\"source file missing: %v\", err)\n}\nok, err := RemoteFileCopyCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: \"wsh://host/correct/path.txt\", DestUri: \"/tmp/out\"})","handlingStrategy":"validation","validationCode":"info, err := wshclient.RemoteFileInfoCommand(rpc, srcPath, &wshrpc.RpcOpts{Route: wshutil.MakeConnectionRouteId(host), Timeout: 10000})\nif err != nil {\n    return fmt.Errorf(\"source %q unreachable: %w\", srcUri, err)\n}","typeGuard":"func sourceFileAvailable(err error) bool { return err == nil }","tryCatchPattern":"ok, err := RemoteFileCopyCommand(ctx, data)\nif err != nil {\n    if strings.Contains(err.Error(), \"cannot get info for source file\") {\n        var pathErr *fs.PathError\n        if errors.As(err, &pathErr) && errors.Is(pathErr, fs.ErrNotExist) {\n            // handle missing source\n        }\n    }\n    return err\n}","preventionTips":["Stat the source file with RemoteFileInfoCommand before copying.","Confirm the source host connection is live before issuing remote RPCs.","Use exact, verified URIs (wsh ls / tab completion) rather than hand-typed paths.","Set a reasonable opts.Timeout to fail fast on dead connections."],"tags":["file-copy","rpc","remote-file-info","wave-terminal"],"backgroundTag":"remote-file-not-found","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}