{"record":{"id":"3bf308f8c3434651","repo":"charmbracelet/glow","slug":"http-status-d","errorCode":null,"errorMessage":"HTTP status %d","messagePattern":"HTTP status (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"main.go","lineNumber":99,"sourceCode":"\tsrc, err := readmeURL(arg)\n\tif src != nil && err == nil {\n\t\t// if there's an error, try next methods...\n\t\treturn src, nil\n\t}\n\n\t// HTTP(S) URLs:\n\tif u, err := url.ParseRequestURI(arg); err == nil && strings.Contains(arg, \"://\") { //nolint:nestif\n\t\tif u.Scheme != \"\" {\n\t\t\tif u.Scheme != \"http\" && u.Scheme != \"https\" {\n\t\t\t\treturn nil, fmt.Errorf(\"%s is not a supported protocol\", u.Scheme)\n\t\t\t}\n\t\t\t// consumer of the source is responsible for closing the ReadCloser.\n\t\t\tresp, err := http.Get(u.String()) //nolint: noctx,bodyclose\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"unable to get url: %w\", err)\n\t\t\t}\n\t\t\tif resp.StatusCode != http.StatusOK {\n\t\t\t\treturn nil, fmt.Errorf(\"HTTP status %d\", resp.StatusCode)\n\t\t\t}\n\t\t\treturn &source{resp.Body, u.String()}, nil\n\t\t}\n\t}\n\n\t// a directory:\n\tif len(arg) == 0 {\n\t\t// use the current working dir if no argument was supplied\n\t\targ = \".\"\n\t}\n\tst, err := os.Stat(arg)\n\tif err == nil && st.IsDir() { //nolint:nestif\n\t\tvar src *source\n\t\t_ = filepath.Walk(arg, func(path string, _ os.FileInfo, err error) error {\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfor _, v := range readmeNames {","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/charmbracelet/glow/blob/e3970c813d93da1ea84edfca90c289d9afb82242/main.go#L81-L117","documentation":"After a successful GET, glow requires exactly http.StatusOK; any other final status code becomes this error with the numeric code. http.Get follows redirects automatically, so the reported code is that of the last response in the chain. The message shows only the number, not the reason phrase or URL, so the operator must map the code to a cause themselves.","triggerScenarios":"404 for a wrong URL; 403 from hotlink protection, WAF rules, or expired presigned URLs; 429 rate limiting (common when fetching GitHub raw content); 5xx server errors; 204 from API endpoints that return no content.","commonSituations":"Stale documentation links, GitHub rate limits on raw.githubusercontent.com, expired S3 presigned URLs, origin-server outages behind a CDN.","solutions":["Open the URL with curl -I to confirm which status is returned","404: fix the URL; 403: check auth/hotlinking/expiry; 429: wait and retry","5xx: retry later - it is a server-side problem","If a redirect target fails, fetch the final URL directly"],"exampleFix":"// before\nif resp.StatusCode != http.StatusOK {\n\treturn nil, fmt.Errorf(\"HTTP status %d\", resp.StatusCode)\n}\n\n// after\nif resp.StatusCode != http.StatusOK {\n\treturn nil, fmt.Errorf(\"GET %s: %s\", u.String(), resp.Status)\n}","handlingStrategy":"validation","validationCode":"func urlReturns200(raw string) error {\n\tres, err := http.Head(raw) //nolint:noctx\n\tif err != nil { return err }\n\tdefer res.Body.Close()\n\tif res.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"precheck: %s for %s\", res.Status, raw)\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate links return 200 before passing them to glow","Cache remote documents instead of re-fetching every run","Handle 429 with a wait-and-retry policy upstream of glow"],"tags":["http","status-code","remote-content"],"backgroundTag":null,"analyzedSha":"e3970c813d93da1ea84edfca90c289d9afb82242","analyzedAt":"2026-08-15T22:50:54.304Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}