{"record":{"id":"be3f9f83978037a5","repo":"coreybutler/nvm-windows","slug":"failed-to-set-permissions-on-destination-file-w","errorCode":null,"errorMessage":"failed to set permissions on destination file: %w","messagePattern":"failed to set permissions on destination file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/utility/rename.go","lineNumber":80,"sourceCode":"\tdestFile, err := os.Create(new)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create destination file: %w\", err)\n\t}\n\tdefer destFile.Close()\n\n\t_, err = io.Copy(destFile, srcFile)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to copy data: %w\", err)\n\t}\n\n\t// Copy file permissions\n\tinfo, err := srcFile.Stat()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get source file info: %w\", err)\n\t}\n\terr = os.Chmod(new, info.Mode())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to set permissions on destination file: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// copyDir recursively copies a directory from old path to new path.\nfunc copyDir(old, new string) error {\n\tentries, err := os.ReadDir(old)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read source directory: %w\", err)\n\t}\n\n\t// Ensure destination directory exists\n\terr = os.MkdirAll(new, os.ModePerm)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create destination directory: %w\", err)\n\t}\n","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/coreybutler/nvm-windows/blob/5b18223ca19ff50d707f35410dbc6bd440a9f74d/src/utility/rename.go#L62-L98","documentation":"In copyFile(), after copying data and stat-ing the source, os.Chmod(new, info.Mode()) clones permissions onto the destination. This error means the chmod failed. On Windows, Chmod only toggles the read-only bit, so it fails mainly when the destination handle is still open in a conflicting mode, the file is read-only, or the destination is on a filesystem that rejects attribute changes (some FAT/network mounts).","triggerScenarios":"copyFile where the destination was just written but is locked (destFile not yet closed when Chmod runs), the destination is on a read-only or non-NTFS mount, or the wrapped error is ERROR_ACCESS_DENIED from a filter driver.","commonSituations":"Copying onto FAT32/exFAT USB drives or network shares with restricted attribute semantics; antivirus holding the fresh file; destination inside a read-only container.","solutions":["Move destFile.Close() before os.Chmod so the handle is released first, then retry.","If the destination filesystem ignores/denies mode changes, skip Chmod for non-critical copies (data is already intact).","Clear read-only attributes on the destination directory and retry.","Copy to an NTFS volume if preserving mode matters."],"exampleFix":"// before\ndefer destFile.Close()\n_, err = io.Copy(destFile, srcFile)\n...\nerr = os.Chmod(new, info.Mode())\n\n// after: close destination before chmod so the handle does not conflict\n_, err = io.Copy(destFile, srcFile)\nif err != nil { return fmt.Errorf(\"failed to copy data: %w\", err) }\nif cerr := destFile.Close(); cerr != nil { return fmt.Errorf(\"failed to close destination file: %w\", cerr) }\nerr = os.Chmod(new, info.Mode())","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := copyAcrossDrives(old, new); err != nil && strings.Contains(err.Error(), \"set permissions\") {\n    // contents copied; chmod is cosmetic on Windows — accept\n    err = nil\n}","preventionTips":["Close destination handles before calling Chmod.","Prefer NTFS destinations when mode preservation matters.","Skip Chmod when the destination filesystem ignores Unix modes."],"tags":["filesystem","chmod","copy","windows","file-permissions"],"backgroundTag":null,"analyzedSha":"5b18223ca19ff50d707f35410dbc6bd440a9f74d","analyzedAt":"2026-08-15T10:06:51.428Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}