coreybutler/nvm-windows · error

failed to open source file: %w

Error message

failed to open source file: %w

What it means

First step of copyFile(): os.Open on the source file failed. The wrapped *PathError gives the OS reason — most commonly the file does not exist, is locked by a running process, or access is denied. Nothing has been written to the destination yet when this fires.

Source

Thrown at src/utility/rename.go:51

		if err != nil {
			return fmt.Errorf("failed to copy file: %w", err)
		}
	}

	// Remove the original source
	err = os.RemoveAll(old)
	if err != nil {
		return fmt.Errorf("failed to remove source: %w", err)
	}

	return nil
}

// copyFile copies a single file from source (old) to destination (new).
func copyFile(old, new string) error {
	srcFile, err := os.Open(old)
	if err != nil {
		return fmt.Errorf("failed to open source file: %w", err)
	}
	defer srcFile.Close()

	// Ensure destination directory exists
	destDir := filepath.Dir(new)
	err = os.MkdirAll(destDir, os.ModePerm)
	if err != nil {
		return fmt.Errorf("failed to create destination directory: %w", err)
	}

	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 {

View on GitHub (pinned to 5b18223ca1)

Solutions

  1. Close/kill processes using the file (node.exe, npm, editors) and retry.
  2. Verify the path exists immediately before the copy; if it vanished, a concurrent nvm operation raced you — re-run install/use.
  3. Run elevated for 'Access is denied' errors.
  4. Enable Windows long paths (LongPathsEnabled=1) for deep node_modules paths.
Defensive patterns

Strategy: validation

Validate before calling

if f, err := os.Open(old); err != nil { return fmt.Errorf("source unreadable: %w", err) } else { f.Close() }

Try / catch

if err := copyAcrossDrives(old, new); err != nil {
    if errors.Is(err, os.ErrNotExist) { /* re-run nvm install to restore source */ }
    if errors.Is(err, os.ErrPermission) { /* elevate or unlock file */ }
}

Prevention

When it happens

Trigger: copyFile(old, new) called from Rename() or copyDir() where 'old' was removed between ReadDir/stat and open, is held with an exclusive lock (running executable), or the user lacks read permission.

Common situations: Copying a node version whose node.exe is currently executing; racing with another nvm command deleting the same tree; long paths over 260 chars without long-path support enabled.

Related errors


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