{"record":{"id":"fe35339cad41742b","repo":"wavetermdev/waveterm","slug":"cannot-create-destination-file-q-w","errorCode":null,"errorMessage":"cannot create destination file %q: %w","messagePattern":"cannot create destination file %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshremote/wshremote_file.go","lineNumber":167,"sourceCode":"\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()\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}","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshremote/wshremote_file.go#L149-L185","documentation":"After validating the source and resolving the destination path, the command opens the destination with os.OpenFile(O_CREATE|O_WRONLY|O_TRUNC, mode from source). This error wraps the OS-level failure to create or truncate that local destination file; the wrapped cause carries the exact reason (permissions, missing directory, disk full, etc.).","triggerScenarios":"os.OpenFile(destFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, srcFileInfo.Mode) fails: destination directory does not exist, no write permission, destFilePath is itself a directory, or the filesystem is read-only/full.","commonSituations":"Copy destination URI points into a nonexistent directory; running the copy from a user without write access to the destination; destination path is an existing directory; disk quota exceeded.","solutions":["Ensure the destination directory exists (create it with os.MkdirAll or wsh mkdir before copying).","Check write permissions on the destination directory and that destFilePath is not itself a directory.","Read the wrapped cause (%w): errors.Is(err, fs.ErrNotExist) → create dir; fs.ErrPermission → fix perms; syscall.ENOSPC → free disk space.","Choose a writable destination path (e.g. under the user's home) via ExpandHomeDir-aware URIs."],"exampleFix":"// before\nRemoteFileCopyCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: src, DestUri: \"/root/out/file.txt\"})\n// after\nos.MkdirAll(\"/home/me/out\", 0o755)\nRemoteFileCopyCommand(ctx, wshrpc.CommandFileCopyData{SrcUri: src, DestUri: \"file:///home/me/out/file.txt\"})","handlingStrategy":"validation","validationCode":"destDir := filepath.Dir(destPath)\nif info, err := os.Stat(destDir); err != nil || !info.IsDir() {\n    return fmt.Errorf(\"destination dir %s missing\", destDir)\n}\nif info, err := os.Stat(destPath); err == nil && info.IsDir() {\n    return fmt.Errorf(\"destination %s is a directory\", destPath)\n}\nif err := unix.Access(destDir, unix.W_OK); err != nil {\n    return fmt.Errorf(\"no write permission on %s\", destDir)\n}","typeGuard":"func destWritable(path string) bool {\n    d := filepath.Dir(path)\n    fi, err := os.Stat(d)\n    return err == nil && fi.IsDir() && unix.Access(d, unix.W_OK) == nil\n}","tryCatchPattern":"ok, err := RemoteFileCopyCommand(ctx, data)\nif err != nil {\n    if strings.Contains(err.Error(), \"cannot create destination file\") {\n        var pe *fs.PathError\n        if errors.As(err, &pe) {\n            switch {\n            case errors.Is(pe, fs.ErrNotExist): os.MkdirAll(filepath.Dir(pe.Path), 0o755)\n            case errors.Is(pe, fs.ErrPermission): return fmt.Errorf(\"check permissions on %s\", pe.Path)\n            }\n        }\n    }\n    return err\n}","preventionTips":["Create the destination directory (MkdirAll) before copying.","Ensure the destination path points to a file, not an existing directory.","Verify write permissions and free disk space on the destination volume.","Use home-relative destinations (~/...) so ExpandHomeDirSafe resolves to a writable path."],"tags":["file-copy","filesystem","permissions","wave-terminal"],"backgroundTag":"file-open-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}