coreybutler/nvm-windows · error

Unable to move directory %s to node_modules: %v

Error message

Unable to move directory %s to node_modules: %v

What it means

Sent (Done: true) when moveNpmErr != nil after install tried to move the freshly downloaded npm into the version's node_modules directory (the npmSourcePath rename). The version directory itself was already renamed into env.root, so node is installed but its bundled npm is missing.

Source

Thrown at src/nvm.go:810

						moveNpmErr = utility.Rename(npmSourcePath, filepath.Join(root, "v"+version, "node_modules", "npm"))
						if moveNpmErr == nil {
							break
						}
					}
				}

				if err == nil && moveNpmErr == nil {
					err = utility.Rename(filepath.Join(root, "v"+version), filepath.Join(env.root, "v"+version))
					if err != nil {
						status <- Status{Err: err}
					}
					if show_progress {
						status <- Status{Done: true}
					} else {
						status <- Status{Text: fmt.Sprintf("Installation complete. If you want to use this version, type\n\nnvm use %s", version), Done: true}
					}
				} else if moveNpmErr != nil {
					status <- Status{Err: fmt.Errorf("Unable to move directory %s to node_modules: %v", npmSourcePath, moveNpmErr), Done: true}
				} else {
					status <- Status{Err: fmt.Errorf("Failed to extract npm: %v", err), Done: true}
				}
			} else {
				err = utility.Rename(filepath.Join(root, "v"+version), filepath.Join(env.root, "v"+version))
				if err != nil {
					status <- Status{Err: err}
				}

				npmurl := web.GetFullNpmUrl(version)
				if show_progress {
					// Send special error notification with link to npm release when it cannot be downloaded
					notify(Notification{
						Title:   "Download Failure (npm)",
						Message: fmt.Sprintf("Please download npm v%s manually and extract to %s\\v%s", version, env.root, version),
						Icon:    "error",
						Actions: []Action{
							{Type: "protocol", Label: "Manually Download", URI: npmurl},

View on GitHub (pinned to 5b18223ca1)

Solutions

  1. Fully remove the broken install first: `nvm uninstall <version>` (or delete <NVM_HOME>\v<version>), then `nvm install <version>` again.
  2. Run the shell elevated (Administrator) so renames under the nvm root succeed.
  3. Exclude the nvm root from antivirus real-time scanning.
  4. Keep NVM_HOME on a local, non-synced disk.

Example fix

# before
nvm install 20.11.0   # retries over a half-installed v20.11.0
# after
nvm uninstall 20.11.0
nvm install 20.11.0
Defensive patterns

Strategy: fallback

Validate before calling

# bash: detect a previous partial install before reinstalling
if [ -d "$NVM_HOME/v$V/node_modules/npm" ] || [ -d "$NVM_HOME/v$V" ]; then
  nvm uninstall "$V" 2>/dev/null || rm -rf "$NVM_HOME/v$V"
fi
nvm install "$V"

Try / catch

nvm install "$V" || { nvm uninstall "$V"; nvm install "$V"; }

Prevention

When it happens

Trigger: `nvm install <version>` where moving npmSourcePath into <root>\v<version>\node_modules fails: destination exists from a previous partial install, file locked by AV/indexer, or permissions on the nvm root.

Common situations: Retrying an install that previously half-completed (leftover node_modules\npm); antivirus holding handles on freshly written files; nvm root on a network drive or synced folder with unreliable rename semantics.

Related errors


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