{"record":{"id":"7ca9d3c25afe1c0b","repo":"JanDeDobbeleer/oh-my-posh","slug":"failed-to-get-s-release","errorCode":null,"errorMessage":"failed to get %s release","messagePattern":"failed to get (.+?) release","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/font/fonts.go","lineNumber":122,"sourceCode":"\t\tURL:    assets[0].URL,\n\t\tFolder: \"ttf/\",\n\t}, nil\n}\n\nfunc fetchFontAssets(repo string) ([]*Asset, error) {\n\tctx, cancelF := context.WithTimeout(context.Background(), time.Second*time.Duration(20))\n\tdefer cancelF()\n\n\trepoURL := \"https://api.github.com/repos/\" + repo + \"/releases/latest\"\n\treq, err := httplib.NewRequestWithContext(ctx, \"GET\", repoURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treq.Header.Add(\"Accept\", \"application/vnd.github.v3+json\")\n\tresponse, err := http.HTTPClient.Do(req)\n\tif err != nil || response.StatusCode != httplib.StatusOK {\n\t\treturn nil, fmt.Errorf(\"failed to get %s release\", repo)\n\t}\n\n\tdefer response.Body.Close()\n\n\tvar release release\n\terr = json.NewDecoder(response.Body).Decode(&release)\n\tif err != nil {\n\t\treturn nil, errors.New(\"failed to parse nerd fonts release\")\n\t}\n\n\tvar fonts []*Asset\n\tfor _, asset := range release.Assets {\n\t\tif asset.State == \"uploaded\" && strings.HasSuffix(asset.Name, \".zip\") {\n\t\t\tasset.Name = strings.TrimSuffix(asset.Name, \".zip\")\n\t\t\tfonts = append(fonts, asset)\n\t\t}\n\t}\n","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/cli/font/fonts.go#L104-L140","documentation":"`fetchFontAssets` requests the GitHub release metadata for a font repository (e.g. ryanoasis/nerd-fonts) and returns this error when the HTTP client errors or the response status is not 200. It collapses both transport failures and bad status codes into one message naming the repo, so GitHub API rate limits and outages both surface here.","triggerScenarios":"`http.HTTPClient.Do(req)` returns an error, or `response.StatusCode != httplib.StatusOK` in `fetchFontAssets(repo)`, called by `fonts()` and `CascadiaCode`. Most common: 403 from unauthenticated GitHub API rate limiting (60 req/hr per IP).","commonSituations":"Shared CI runner IP exhausted the unauthenticated GitHub rate limit; GitHub outage; corporate proxy blocking api.github.com; DNS failure offline.","solutions":["Wait for the GitHub rate limit to reset (check `curl -s https://api.github.com/rate_limit`) or authenticate via GH_TOKEN if applicable","Retry after verifying network access to api.github.com","Install the font manually: download the zip from the releases page and run `oh-my-posh font install <local>.zip`","Check status.github.com for ongoing incidents","If behind a proxy, configure HTTPS_PROXY correctly"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"rate, _ := http.Get(\"https://api.github.com/rate_limit\")\n// inspect X-RateLimit-Remaining header before batch installs\nif remaining == 0 { wait until reset before calling `oh-my-posh font` }","typeGuard":null,"tryCatchPattern":"for attempt := 0; attempt < 3; attempt++ {\n\terr := installFont(\"FiraCode\")\n\tif err == nil { return nil }\n\tif strings.Contains(err.Error(), \"failed to get\") {\n\t\ttime.Sleep(time.Duration(1<<attempt) * time.Second) // backoff for rate limit\n\t\tcontinue\n\t}\n\treturn err\n}","preventionTips":["Avoid mass font installs from shared CI IPs that exhaust the 60/hr unauthenticated GitHub limit","Prefer downloading the zip directly from releases.com URL and installing the local file","Monitor status.github.com during incidents"],"tags":["network","github-api","rate-limit"],"backgroundTag":"github-api-rate-limit","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}