{"record":{"id":"27d4693687aca57d","repo":"JanDeDobbeleer/oh-my-posh","slug":"failed-to-download-zip-file-s-s","errorCode":null,"errorMessage":"failed to download zip file: %s\n→ %s","messagePattern":"failed to download zip file: (.+?)\n→ (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/font/download.go","lineNumber":84,"sourceCode":"\tcontentType := httplib.DetectContentType(data)\n\treturn contentType == \"application/zip\"\n}\n\nfunc getRemoteFile(location string, report func(fraction float64)) (data []byte, err error) {\n\treq, err := httplib.NewRequestWithContext(context.Background(), \"GET\", location, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tresp, err := http.HTTPClient.Do(req)\n\tif err != nil {\n\t\treturn\n\t}\n\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != httplib.StatusOK {\n\t\treturn data, fmt.Errorf(\"failed to download zip file: %s\\n→ %s\", resp.Status, location)\n\t}\n\n\treader := ui.NewReader(resp.Body, resp.ContentLength, report)\n\n\tdata, err = io.ReadAll(reader)\n\tif err != nil {\n\t\treturn\n\t}\n\n\treturn\n}\n\n// Download keeps the old name for callers that need no progress reporting (see font.Apply, which\n// runs under DSC with nothing drawing).\nfunc Download(fontURL string) ([]byte, error) {\n\treturn download(fontURL, nil)\n}\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/cli/font/download.go#L66-L102","documentation":"`getRemoteFile` performs the HTTP GET for the font archive and errors when the server responds with a non-200 status, wrapping `resp.Status` (e.g. \"404 Not Found\") and the requested `location`. It is the network-level failure of the font download step; read of the body is aborted before any zip validation happens.","triggerScenarios":"`http.HTTPClient.Do` returned a response whose `StatusCode != httplib.StatusOK` inside `getRemoteFile`, called from `download`. Any 4xx/5xx — 404 (asset/repo renamed), 403 (rate limited or private repo), 5xx (server error).","commonSituations":"GitHub API rate limiting (403 with rate-limit headers); font release asset renamed after a Nerd Fonts release; offline or DNS-failing network; proxy requiring auth returning 407.","solutions":["Check `resp.Status` in the message: 404 → fix the URL/asset name; 403 → check rate limit/auth; 5xx → retry later","Wait for GitHub API rate limit reset or authenticate requests if hitting api.github.com heavily","Verify network/proxy connectivity (`curl -I <location>`)","Retry the `oh-my-posh font` command after confirming the URL works in a browser","Pin to a still-existing release tag if the font release was renamed/removed"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"resp, err := http.Head(url)\nif err != nil || resp.StatusCode != http.StatusOK {\n\t// fail fast before invoking the installer\n\tlog.Fatalf(\"URL not reachable: %v (status %v)\", err, resp)\n}","typeGuard":null,"tryCatchPattern":"if err := installFont(name); err != nil {\n\tvar netErr net.Error\n\tif errors.As(err, &netErr) || strings.Contains(err.Error(), \"failed to download zip file\") {\n\t\ttime.Sleep(retryBackoff)\n\t\treturn installFont(name) // bounded retry\n\t}\n\treturn err\n}","preventionTips":["Handle 403 rate limits with backoff before retrying","Pin to immutable release asset URLs that won't 404 later","Verify connectivity/proxy settings before running the installer"],"tags":["network","http","download"],"backgroundTag":"http-request-failed","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}