coreybutler/nvm-windows · error

Error computing checksum: %v

Error message

Error computing checksum: %v

What it means

nvm-windows computes an MD5 checksum of the downloaded assets.zip via computeMD5Checksum before applying the update. This error means reading the zip file or hashing it failed at the OS level — the file could not be opened or read. It is not a mismatch (that is error 43); it is an I/O failure on the temp file that was just written.

Source

Thrown at src/upgrade/upgrade.go:411

	os.WriteFile(filepath.Join(tmp, "assets.zip"), body, os.ModePerm)
	os.Mkdir(filepath.Join(tmp, "assets"), os.ModePerm)

	source = source + ".checksum.txt"
	body, err = get(source)
	if err != nil {
		return fmt.Errorf("error: failed to download checksum: %v\n", err)
	}

	os.WriteFile(filepath.Join(tmp, "assets.zip.checksum.txt"), body, os.ModePerm)

	filePath := filepath.Join(tmp, "assets.zip")                  // path to the file you want to validate
	checksumFile := filepath.Join(tmp, "assets.zip.checksum.txt") // path to the checksum file

	// Step 1: Compute the MD5 checksum of the file
	status <- Status{Text: "verifying checksum..."}
	computedChecksum, err := computeMD5Checksum(filePath)
	if err != nil {
		status <- Status{Err: fmt.Errorf("Error computing checksum: %v", err)}
	}

	// Step 2: Read the checksum from the .checksum.txt file
	storedChecksum, err := readChecksumFromFile(checksumFile)
	if err != nil {
		status <- Status{Err: err}
	}

	// Step 3: Compare the computed checksum with the stored checksum
	if strings.ToLower(computedChecksum) != strings.ToLower(storedChecksum) {
		status <- Status{Err: fmt.Errorf("cannot validate update file (checksum mismatch)")}
	}

	status <- Status{Text: "extracting update..."}
	if err := unzip(filepath.Join(tmp, "assets.zip"), filepath.Join(tmp, "assets")); err != nil {
		status <- Status{Err: err}
	}

View on GitHub (pinned to 5b18223ca1)

Solutions

  1. Check free space on the drive hosting %TEMP% and clear stale temp files.
  2. Add an exclusion for the nvm root / nvm-upgrade-* temp pattern in antivirus, or temporarily disable real-time scanning during upgrade.
  3. Re-run the upgrade — if the zip was deleted by a scanner, a fresh download usually hashes fine.
  4. Verify the file exists and is readable manually: download the zip and run certutil -hashfile assets.zip MD5.
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check that the zip landed intact before hashing
fi, err := os.Stat(filepath.Join(tmp, "assets.zip"))
if err != nil || fi.Size() == 0 {
    return fmt.Errorf("downloaded zip missing or empty")
}

Try / catch

Handle as a transient I/O failure: report via the status channel, keep the previous installation (untouched yet), and let the user retry after clearing temp/AV conditions.

Prevention

When it happens

Trigger: os.Open/os.ReadFile of %TEMP%\nvm-upgrade-*/assets.zip failing because antivirus quarantined the freshly downloaded zip; the temp directory was cleaned mid-upgrade; disk full causing a truncated/absent file; another process holding an exclusive lock on the file (Windows sharing violation).

Common situations: Real-time antivirus (Defender, third-party) deleting or locking a just-downloaded exe/zip; TEMP directory on a disk under space pressure; aggressive 'temp cleaner' utilities running concurrently with the upgrade.

Related errors


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