{"record":{"id":"0651c8f72ad57c49","repo":"coreybutler/nvm-windows","slug":"error-failed-to-download-new-version-v","errorCode":null,"errorMessage":"error: failed to download new version: %v\n","messagePattern":"error: failed to download new version: (.+?)\n","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/upgrade/upgrade.go","lineNumber":390,"sourceCode":"\t} else {\n\t\tstatus <- Status{Text: \"nvm is up to date\", Done: true}\n\t\treturn nil\n\t}\n\n\t// Make temp directory\n\ttmp, err := os.MkdirTemp(\"\", \"nvm-upgrade-*\")\n\tif err != nil {\n\t\tstatus <- Status{Err: fmt.Errorf(\"error: failed to create temporary directory: %v\\n\", err)}\n\t}\n\tdefer os.RemoveAll(tmp)\n\n\t// Download the new app\n\tsource := update.SourceURL\n\t// source := fmt.Sprintf(update.SourceURL, update.Version)\n\t// source := fmt.Sprintf(update.SourceURL, \"1.1.11\") // testing\n\tbody, err := get(source)\n\tif err != nil {\n\t\tstatus <- Status{Err: fmt.Errorf(\"error: failed to download new version: %v\\n\", err)}\n\t}\n\n\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...\"}","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/coreybutler/nvm-windows/blob/5b18223ca19ff50d707f35410dbc6bd440a9f74d/src/upgrade/upgrade.go#L372-L408","documentation":"nvm-windows' self-upgrade downloads the new release zip from update.SourceURL into a temp directory. This error means the HTTP GET for the main assets zip (e.g. nvm-noinstall.zip on GitHub) failed. The underlying %v is either a transport error (DNS, TLS, proxy, offline) or a non-200 status from the get() helper. Note this branch sends to a status channel rather than returning, so the goroutine continues with an empty body unless the caller aborts.","triggerScenarios":"Running 'nvm install' of a new nvm-windows release or the automatic update check when the machine cannot reach github.com / the release mirror; corporate proxy or TLS interception rejecting the request; the release URL in the update manifest pointing at a deleted/moved asset (HTTP 404); offline machine.","commonSituations":"Proxy-locked corporate networks blocking raw.githubusercontent/github releases; firewall or antivirus intercepting the download; a temporarily missing release asset after a GitHub release edit; DNS failure on offline CI agents.","solutions":["Verify connectivity to the update SourceURL (curl -L <SourceURL>) and check the status code manually.","If behind a proxy, set HTTPS_PROXY/HTTP_PROXY or configure the system proxy so the Go http.Client can use it.","Confirm the release asset actually exists at SourceURL (asset renamed or release marked pre-release/draft yields 404).","Re-run the upgrade; transient GitHub 5xx failures resolve themselves.","If it persists, download the nvm-noinstall.zip manually and replace the nvm root directory by hand."],"exampleFix":"// before\nbody, err := get(source)\nif err != nil {\n    status <- Status{Err: fmt.Errorf(\"error: failed to download new version: %v\\n\", err)}\n}\n\n// after: stop the upgrade instead of continuing with an empty body\nbody, err := get(source)\nif err != nil {\n    status <- Status{Err: fmt.Errorf(\"error: failed to download new version: %v\\n\", err)}\n    return err\n}","handlingStrategy":"retry","validationCode":"// Verify the update source is reachable before starting the upgrade\nresp, err := http.Head(update.SourceURL)\nif err != nil || resp.StatusCode != http.StatusOK {\n    fmt.Println(\"update source unreachable; skipping self-upgrade:\", err)\n    return\n}","typeGuard":null,"tryCatchPattern":"In Go: treat any status-channel Err from the download phase as terminal — drain the channel, report, and do not let the goroutine continue with an empty body. Wrap with a bounded retry (e.g. 3 attempts, exponential backoff) for transport errors.","preventionTips":["Configure proxy env vars (HTTP_PROXY/HTTPS_PROXY) on restricted networks before upgrading.","Keep the machine online and DNS healthy; test with curl -L against the release URL.","Pin upgrades to stable release tags rather than latest."],"tags":["network","upgrade","download","nvm-windows"],"backgroundTag":null,"analyzedSha":"5b18223ca19ff50d707f35410dbc6bd440a9f74d","analyzedAt":"2026-08-15T10:06:51.428Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}