coreybutler/nvm-windows · error

failed to create destination directory %s: %v

Error message

failed to create destination directory %s: %v

What it means

copyDirContents starts by creating the destination directory tree with os.MkdirAll before walking the source. This error means that MkdirAll failed — the destination path cannot be created or already exists as a file. During upgrade the destination is the live NVM_HOME, so failures here are permission or path-shape problems, not missing parents (MkdirAll creates those).

Source

Thrown at src/upgrade/upgrade.go:960

	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)
		}

		// Construct the corresponding path in the destination directory
		relPath, err := filepath.Rel(srcDir, srcPath)
		if err != nil {
			return fmt.Errorf("failed to get relative path for %s: %v", srcPath, err)
		}

		dstPath := filepath.Join(dstDir, relPath)

		// If it's a directory, ensure it's created in the destination
		if info.IsDir() {

View on GitHub (pinned to 5b18223ca1)

Solutions

  1. Run the upgrade from an elevated prompt.
  2. Verify every component of the destination path is a directory, not a file, and fix any that are wrong (delete the stray file).
  3. If NVM_HOME is on a share, reconnect it or move NVM_HOME local.
  4. Reinstall nvm-windows if the directory structure is corrupted.
Defensive patterns

Strategy: validation

Validate before calling

// Verify the destination can be a directory before the tree copy
if fi, err := os.Stat(dstDir); err == nil && !fi.IsDir() {
    return fmt.Errorf("destination exists but is a file: %s", dstDir)
}
if err := os.MkdirAll(dstDir, 0755); err != nil {
    return fmt.Errorf("cannot create %s (permissions? run elevated): %v", dstDir, err)
}

Try / catch

Fail fast with the dstDir named in the error; direct the user to elevation or ACL repair. Do not retry unchanged — permission failures do not self-heal.

Prevention

When it happens

Trigger: NVM_HOME exists but the invoking user lacks write rights (Program Files install without elevation); a path component of dst is an existing regular file (e.g. a file named 'assets' where a directory is expected); NVM_HOME on an unavailable network share; path exceeds MAX_PATH on deep trees.

Common situations: Non-admin upgrade of a machine-wide install; corrupted install tree where a directory was replaced by a file; disconnected mapped drive hosting NVM_HOME.

Related errors


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