{"record":{"id":"002e06d299581a16","repo":"coreybutler/nvm-windows","slug":"error-computing-checksum-v","errorCode":null,"errorMessage":"Error computing checksum: %v","messagePattern":"Error computing checksum: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/upgrade/upgrade.go","lineNumber":411,"sourceCode":"\tos.WriteFile(filepath.Join(tmp, \"assets.zip\"), body, os.ModePerm)\n\tos.Mkdir(filepath.Join(tmp, \"assets\"), os.ModePerm)\n\n\tsource = source + \".checksum.txt\"\n\tbody, err = get(source)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error: failed to download checksum: %v\\n\", err)\n\t}\n\n\tos.WriteFile(filepath.Join(tmp, \"assets.zip.checksum.txt\"), body, os.ModePerm)\n\n\tfilePath := filepath.Join(tmp, \"assets.zip\")                  // path to the file you want to validate\n\tchecksumFile := filepath.Join(tmp, \"assets.zip.checksum.txt\") // path to the checksum file\n\n\t// Step 1: Compute the MD5 checksum of the file\n\tstatus <- Status{Text: \"verifying checksum...\"}\n\tcomputedChecksum, err := computeMD5Checksum(filePath)\n\tif err != nil {\n\t\tstatus <- Status{Err: fmt.Errorf(\"Error computing checksum: %v\", err)}\n\t}\n\n\t// Step 2: Read the checksum from the .checksum.txt file\n\tstoredChecksum, err := readChecksumFromFile(checksumFile)\n\tif err != nil {\n\t\tstatus <- Status{Err: err}\n\t}\n\n\t// Step 3: Compare the computed checksum with the stored checksum\n\tif strings.ToLower(computedChecksum) != strings.ToLower(storedChecksum) {\n\t\tstatus <- Status{Err: fmt.Errorf(\"cannot validate update file (checksum mismatch)\")}\n\t}\n\n\tstatus <- Status{Text: \"extracting update...\"}\n\tif err := unzip(filepath.Join(tmp, \"assets.zip\"), filepath.Join(tmp, \"assets\")); err != nil {\n\t\tstatus <- Status{Err: err}\n\t}\n","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/coreybutler/nvm-windows/blob/5b18223ca19ff50d707f35410dbc6bd440a9f74d/src/upgrade/upgrade.go#L393-L429","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check free space on the drive hosting %TEMP% and clear stale temp files.","Add an exclusion for the nvm root / nvm-upgrade-* temp pattern in antivirus, or temporarily disable real-time scanning during upgrade.","Re-run the upgrade — if the zip was deleted by a scanner, a fresh download usually hashes fine.","Verify the file exists and is readable manually: download the zip and run certutil -hashfile assets.zip MD5."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Pre-check that the zip landed intact before hashing\nfi, err := os.Stat(filepath.Join(tmp, \"assets.zip\"))\nif err != nil || fi.Size() == 0 {\n    return fmt.Errorf(\"downloaded zip missing or empty\")\n}","typeGuard":null,"tryCatchPattern":"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.","preventionTips":["Exclude nvm temp dirs from real-time antivirus scanning.","Keep %TEMP% on a drive with free space.","Close temp-cleanup utilities during upgrades."],"tags":["filesystem","checksum","antivirus","upgrade"],"backgroundTag":null,"analyzedSha":"5b18223ca19ff50d707f35410dbc6bd440a9f74d","analyzedAt":"2026-08-15T10:06:51.428Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}