coreybutler/nvm-windows · warning
failed to set permissions on destination file: %w
Error message
failed to set permissions on destination file: %w
What it means
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).
Source
Thrown at src/utility/rename.go:80
destFile, err := os.Create(new)
if err != nil {
return fmt.Errorf("failed to create destination file: %w", err)
}
defer destFile.Close()
_, err = io.Copy(destFile, srcFile)
if err != nil {
return fmt.Errorf("failed to copy data: %w", err)
}
// Copy file permissions
info, err := srcFile.Stat()
if err != nil {
return fmt.Errorf("failed to get source file info: %w", err)
}
err = os.Chmod(new, info.Mode())
if err != nil {
return fmt.Errorf("failed to set permissions on destination file: %w", err)
}
return nil
}
// copyDir recursively copies a directory from old path to new path.
func copyDir(old, new string) error {
entries, err := os.ReadDir(old)
if err != nil {
return fmt.Errorf("failed to read source directory: %w", err)
}
// Ensure destination directory exists
err = os.MkdirAll(new, os.ModePerm)
if err != nil {
return fmt.Errorf("failed to create destination directory: %w", err)
}
View on GitHub (pinned to 5b18223ca1)
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.
Example fix
// before
defer destFile.Close()
_, err = io.Copy(destFile, srcFile)
...
err = os.Chmod(new, info.Mode())
// after: close destination before chmod so the handle does not conflict
_, err = io.Copy(destFile, srcFile)
if err != nil { return fmt.Errorf("failed to copy data: %w", err) }
if cerr := destFile.Close(); cerr != nil { return fmt.Errorf("failed to close destination file: %w", cerr) }
err = os.Chmod(new, info.Mode()) Defensive patterns
Strategy: fallback
Try / catch
if err := copyAcrossDrives(old, new); err != nil && strings.Contains(err.Error(), "set permissions") {
// contents copied; chmod is cosmetic on Windows — accept
err = nil
} Prevention
- Close destination handles before calling Chmod.
- Prefer NTFS destinations when mode preservation matters.
- Skip Chmod when the destination filesystem ignores Unix modes.
When it happens
Trigger: 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.
Common situations: Copying onto FAT32/exFAT USB drives or network shares with restricted attribute semantics; antivirus holding the fresh file; destination inside a read-only container.
Related errors
- failed to copy directory: %w
- failed to copy file: %w
- failed to open source file: %w
- failed to create destination directory: %w
- failed to create destination file: %w
AI-assisted analysis of coreybutler/nvm-windows@5b18223ca1 (2026-08-15).
Data as JSON: /api/errors/be3f9f83978037a5.
Report an issue: GitHub.