coreybutler/nvm-windows · warning
failed to set file permissions: %v
Error message
failed to set file permissions: %v
What it means
copyFile's final step applies the source file's permission bits to the destination with os.Chmod, and this error means that failed. On Windows, Chmod maps to SetFileInformationByHandle and can be denied when the destination handle is still open (the deferred Close has not run yet) or when ACLs on the destination forbid the change. The data copy itself already succeeded, so the file exists but may carry default permissions.
Source
Thrown at src/upgrade/upgrade.go:949
return fmt.Errorf("failed to create destination file: %v", err)
}
defer destinationFile.Close()
// Copy contents from the source file to the destination file
_, err = io.Copy(destinationFile, sourceFile)
if err != nil {
return fmt.Errorf("failed to copy file: %v", err)
}
// Optionally, copy file permissions (this can be skipped if not needed)
sourceInfo, err := os.Stat(src)
if err != nil {
return fmt.Errorf("failed to get source file info: %v", err)
}
err = os.Chmod(dst, sourceInfo.Mode())
if err != nil {
return fmt.Errorf("failed to set file permissions: %v", err)
}
return nil
}
// copyDirContents copies all the contents (files and subdirectories) of a source directory to a destination directory.
func copyDirContents(srcDir, dstDir string) error {
// Ensure destination directory exists
err := os.MkdirAll(dstDir, 0755)
if err != nil {
return fmt.Errorf("failed to create destination directory %s: %v", dstDir, err)
}
// Walk through the source directory recursively
err = filepath.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("error accessing %s: %v", srcPath, err)
}View on GitHub (pinned to 5b18223ca1)
Solutions
- Run the upgrade elevated so permission changes under NVM_HOME succeed.
- Check inherited ACLs/attributes on the destination directory (attrib -r, icacls) and clear read-only inheritance.
- Treat as non-fatal if present: the copied bytes are valid; re-running as admin fixes modes.
Example fix
// before
err = os.Chmod(dst, sourceInfo.Mode())
if err != nil {
return fmt.Errorf("failed to set file permissions: %v", err)
}
// after: close handles before chmod and tolerate failure on Windows
destinationFile.Close()
sourceFile.Close()
if err := os.Chmod(dst, sourceInfo.Mode()); err != nil {
// permissions are advisory on Windows; log but do not fail the copy
utility.DebugLogf("chmod %s: %v", dst, err)
} Defensive patterns
Strategy: fallback
Try / catch
Permission mirroring is optional: catch the Chmod error, log it, and return nil so the copied file is used as-is. Only fail when a later exec of the copied binary proves permissions actually matter.
Prevention
- Close destination handles before chmod.
- Run elevated when installing into ACL-protected trees.
- Remember Windows modes are advisory; don't hard-fail on them.
When it happens
Trigger: Destination under a directory with restrictive ACLs (Program Files without elevation); the still-open destinationFile handle conflicting with the mode change; read-only attribute on the destination inherited from the directory.
Common situations: Non-admin installs into protected paths; group-policy ACL inheritance marking files read-only; enterprise lockdown tools reverting permission changes.
Related errors
- failed to create destination directory %s: %v
- Error rolling back node v%s installation: %v.
- Unable to move directory %s to node_modules: %v
- failed to elevate permissions to create symlink
- error: failed to create backup directory: %v
AI-assisted analysis of coreybutler/nvm-windows@5b18223ca1 (2026-08-15).
Data as JSON: /api/errors/c3ff1a647c6e5221.
Report an issue: GitHub.