{"record":{"id":"84c83511e79b52e7","repo":"mislav/hub","slug":"error-s-s-http-d","errorCode":null,"errorMessage":"Error %s: %s (HTTP %d)","messagePattern":"Error (.+?): (.+?) \\(HTTP (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"github/client.go","lineNumber":1206,"sourceCode":"\t\treturn GitHubHost\n\tcase \"api.github.localhost\":\n\t\treturn \"github.localhost\"\n\tdefault:\n\t\treturn host\n\t}\n}\n\nfunc checkStatus(expectedStatus int, action string, response *simpleResponse, err error) error {\n\tif err != nil {\n\t\terrStr := err.Error()\n\t\tif urlErr, isURLErr := err.(*url.Error); isURLErr {\n\t\t\terrStr = fmt.Sprintf(\"%s %s: %s\", urlErr.Op, urlErr.URL, urlErr.Err)\n\t\t}\n\t\treturn fmt.Errorf(\"Error %s: %s\", action, errStr)\n\t} else if response.StatusCode != expectedStatus {\n\t\terrInfo, err := response.ErrorInfo()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Error %s: %s (HTTP %d)\", action, err.Error(), response.StatusCode)\n\t\t}\n\t\treturn FormatError(action, errInfo)\n\t}\n\treturn nil\n}\n\n// FormatError annotates an HTTP response error with user-friendly messages\nfunc FormatError(action string, err error) error {\n\tif e, ok := err.(*errorInfo); ok {\n\t\treturn formatError(action, e)\n\t}\n\treturn err\n}\n\nfunc formatError(action string, e *errorInfo) error {\n\tvar reason string\n\tif s := strings.SplitN(e.Response.Status, \" \", 2); len(s) >= 2 {\n\t\treason = strings.TrimSpace(s[1])","sourceCodeStart":1188,"sourceCodeEnd":1224,"githubUrl":"https://github.com/mislav/hub/blob/5c547ed804368763064e51f3990851e267e88edd/github/client.go#L1188-L1224","documentation":"Also from checkStatus, this variant fires when the HTTP request completed but with an unexpected status code AND the response body could not be parsed into a structured error (response.ErrorInfo() failed). The library then reports the raw error text plus the HTTP status code, e.g. 'Error creating pull request: ... (HTTP 502)'.","triggerScenarios":"Server returned a status != expectedStatus with a body that isn't the expected JSON error format: HTML error pages from proxies/load balancers, 502/503/504 from GitHub, or empty bodies on 4xx/5xx.","commonSituations":"GitHub incident causing 5xx responses; a corporate proxy returning an HTML block page; hitting a misconfigured enterprise GitHub instance returning non-JSON errors; rate-limit pages served as HTML.","solutions":["Note the HTTP code in the message: retry on 5xx after a short delay (usually transient).","Inspect the raw response (curl the same endpoint) to see the non-JSON body.","If a proxy is intercepting, bypass it or fix its configuration for api.github.com.","Check the GitHub status page for ongoing incidents."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func isUnexpectedStatus(err error) bool {\n    return strings.Contains(err.Error(), \"(HTTP \")\n}","tryCatchPattern":"if m := httpStatusRe.FindStringSubmatch(err.Error()); m != nil {\n    code, _ := strconv.Atoi(m[1])\n    if code >= 500 { backoffAndRetry() }\n}","preventionTips":["Retry 5xx responses with backoff — they are usually transient.","Bypass or fix HTML-returning proxies for api.github.com.","Watch the GitHub status page; fail fast during incidents.","On enterprise instances, verify the appliance health before API calls."],"tags":["github-api","http-status","server-error"],"backgroundTag":"unexpected-http-status-code","analyzedSha":"5c547ed804368763064e51f3990851e267e88edd","analyzedAt":"2026-09-01T03:34:15.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}