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

  1. Move destFile.Close() before os.Chmod so the handle is released first, then retry.
  2. If the destination filesystem ignores/denies mode changes, skip Chmod for non-critical copies (data is already intact).
  3. Clear read-only attributes on the destination directory and retry.
  4. 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

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


AI-assisted analysis of coreybutler/nvm-windows@5b18223ca1 (2026-08-15). Data as JSON: /api/errors/be3f9f83978037a5. Report an issue: GitHub.