{"record":{"id":"877c3dc54a603d7c","repo":"coreybutler/nvm-windows","slug":"error-parsing-release-v","errorCode":null,"errorMessage":"error: parsing release: %v","messagePattern":"error: parsing release: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/upgrade/upgrade.go","lineNumber":749,"sourceCode":"\treturn io.ReadAll(resp.Body)\n}\n\nfunc checkForUpdate(url string) (*Update, error) {\n\tu := Update{Assets: []string{}, Warnings: []string{}, VersionWarnings: []string{}}\n\tr := Release{}\n\n\t// Make the HTTP GET request\n\tutility.DebugLogf(\"checking for updates at %s\", url)\n\tbody, err := get(url, false)\n\tif err != nil {\n\t\treturn &u, fmt.Errorf(\"error: reading response body: %v\", err)\n\t}\n\n\t// Parse JSON into the struct\n\tutility.DebugLogf(\"Received:\\n%s\", string(body))\n\terr = json.Unmarshal(body, &r)\n\tif err != nil {\n\t\treturn &u, fmt.Errorf(\"error: parsing release: %v\", err)\n\t}\n\n\tu.Version = r.Version\n\tutility.DebugLogf(\"latest version: %s\", u.Version)\n\n\t// Comment the next line when development is complete\n\t// u.Version = \"2.0.0\"\n\tfor _, asset := range r.Assets {\n\t\tif value, exists := asset[\"name\"]; exists && value.(string) == \"update.exe\" {\n\t\t\tu.Assets = append(u.Assets, value.(string))\n\t\t}\n\t\tif value, exists := asset[\"name\"]; exists && value.(string) == \"nvm-noinstall.zip\" {\n\t\t\tu.SourceURL = asset[\"browser_download_url\"].(string)\n\t\t}\n\t}\n\n\tutility.DebugLogf(\"source URL: %s\", u.SourceURL)\n\tutility.DebugLogf(\"assets: %v\", u.Assets)","sourceCodeStart":731,"sourceCodeEnd":767,"githubUrl":"https://github.com/coreybutler/nvm-windows/blob/5b18223ca19ff50d707f35410dbc6bd440a9f74d/src/upgrade/upgrade.go#L731-L767","documentation":"checkForUpdate unmarshals the fetched release JSON into a Release struct. This error means json.Unmarshal failed: the body is not valid JSON or does not match expectations (wrong types, HTML error page parsed as JSON). Classic causes are a proxy returning an HTML block page with 200, a mirror serving a different schema, or the URL pointing at an HTML page instead of the API JSON.","triggerScenarios":"Captive portal / proxy returning HTML with status 200; update URL misconfigured to a releases web page instead of the JSON API endpoint; a mirror rewriting the response; truncated body from a flaky connection; upstream schema change where a field changes type and the strict struct rejects it.","commonSituations":"Hotel/airport captive portals intercepting the update check; NVM update URL overridden to a third-party mirror with a different feed format; GitHub incident serving error pages; new release format after an nvm-windows version change.","solutions":["Fetch the update URL manually and pipe to a JSON validator to see the actual payload.","If a proxy injects HTML, bypass it or authenticate; the body seen in the debug log (DebugLogf 'Received:') shows exactly what came back.","Point the update-check URL back at the official GitHub API JSON endpoint.","Upgrade nvm-windows manually to a version matching the current feed format."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Sanity-check the payload before unmarshal\ntrimmed := bytes.TrimSpace(body)\nif len(trimmed) == 0 || trimmed[0] != '{' {\n    return &u, fmt.Errorf(\"update feed returned non-JSON (likely proxy/captive portal), first byte %q\", trimmed[0])\n}","typeGuard":null,"tryCatchPattern":"Catch, log the raw body prefix (already done via DebugLogf 'Received:'), and skip the update — never fall back to guessing a version. Distinguish proxy-HTML responses from schema drift in the message.","preventionTips":["Validate content is JSON before unmarshal.","Avoid third-party mirrors that rewrite the feed format.","Pin nvm-windows to a version whose feed schema matches."],"tags":["json","parsing","network","update-check"],"backgroundTag":null,"analyzedSha":"5b18223ca19ff50d707f35410dbc6bd440a9f74d","analyzedAt":"2026-08-15T10:06:51.428Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}