{"record":{"id":"a06f679543b7487c","repo":"kovidgoyal/kitty","slug":"failed-to-rename-temporary-file-used-for-downloadi","errorCode":null,"errorMessage":"Failed to rename temporary file used for downloading to destination: %s with error: %w","messagePattern":"Failed to rename temporary file used for downloading to destination: (.+?) with error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/clipboard/read.go","lineNumber":138,"sourceCode":"\t\tif err != nil {\n\t\t\tself.err = fmt.Errorf(\"Failed to encode image data to %s with error: %w\", self.mime_type, err)\n\t\t}\n\t} else {\n\t\tself.dest.Close()\n\t\tif !self.is_stream {\n\t\t\tf, err := os.OpenFile(self.arg, os.O_CREATE|os.O_RDONLY, 0666)\n\t\t\tif err == nil {\n\t\t\t\tfi, err := f.Stat()\n\t\t\t\tif err == nil {\n\t\t\t\t\tself.dest.Chmod(fi.Mode().Perm())\n\t\t\t\t}\n\t\t\t\tf.Close()\n\t\t\t\tos.Remove(f.Name())\n\t\t\t}\n\t\t\tself.err = os.Rename(self.dest.Name(), self.arg)\n\t\t\tif self.err != nil {\n\t\t\t\tos.Remove(self.dest.Name())\n\t\t\t\tself.err = fmt.Errorf(\"Failed to rename temporary file used for downloading to destination: %s with error: %w\", self.arg, self.err)\n\t\t\t}\n\t\t}\n\t}\n\tself.dest = nil\n}\n\nfunc (self *Output) assign_mime_type(available_mimes []string, aliases map[string][]string) (err error) {\n\tif self.mime_type == \".\" {\n\t\tself.remote_mime_type = \".\"\n\t\treturn\n\t}\n\tif slices.Contains(available_mimes, self.mime_type) {\n\t\tself.remote_mime_type = self.mime_type\n\t\treturn\n\t}\n\tif len(aliases[self.mime_type]) > 0 {\n\t\tfor _, alias := range aliases[self.mime_type] {\n\t\t\tif slices.Contains(available_mimes, alias) {","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/clipboard/read.go#L120-L156","documentation":"When saving clipboard data with a temporary file, the final step renames the temp file onto the destination path. If os.Rename fails (cross-device link, permissions, destination is a directory), the temp file is removed and the error is wrapped with the destination path.","triggerScenarios":"`kitten clipboard getfile dest` where the temp directory (TMPDIR or /tmp) and the destination are on different filesystems so rename(2) returns EXDEV; destination directory not writable; destination path is an existing directory.","commonSituations":"/tmp mounted as tmpfs while the destination is on a network mount (NFS, FUSE, sshfs); read-only or permission-restricted download directories; containers where /tmp and the volume differ in mount device.","solutions":["Set TMPDIR to a directory on the same filesystem as the destination: `TMPDIR=/path/to/dest/dir kitten clipboard getfile dest`","Fix write permissions on the destination directory","Ensure the destination is a file path, not an existing directory"],"exampleFix":"# before\nTMPDIR=/tmp kitten clipboard getfile /mnt/nfs/out.png   # EXDEV\n# after\nTMPDIR=/mnt/nfs kitten clipboard getfile /mnt/nfs/out.png","handlingStrategy":"validation","validationCode":"# same-filesystem tmp dir prevents EXDEV\nexport TMPDIR=\"$(dirname \"$(readlink -f \"$DEST\")\")\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set TMPDIR to the destination's filesystem","Ensure the destination directory is writable and is not itself a directory path"],"tags":["kitty","clipboard","filesystem","rename","cross-device"],"backgroundTag":"rename-cross-device","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}