{"record":{"id":"f17272391891abbe","repo":"micro/go-micro","slug":"api-error-nil-response","errorCode":null,"errorMessage":"API error: nil response","messagePattern":"API error: nil response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/retry.go","lineNumber":57,"sourceCode":"}\n\nfunc (e *HTTPError) StatusCode() int {\n\tif e == nil {\n\t\treturn 0\n\t}\n\treturn e.Code\n}\n\nfunc (e *HTTPError) RetryAfter() time.Duration {\n\tif e == nil {\n\t\treturn 0\n\t}\n\treturn parseRetryAfter(e.Header.Get(\"Retry-After\"), time.Now())\n}\n\nfunc NewHTTPError(resp *http.Response, body []byte) error {\n\tif resp == nil {\n\t\treturn errors.New(\"API error: nil response\")\n\t}\n\treturn &HTTPError{Status: resp.Status, Code: resp.StatusCode, Body: string(body), Header: resp.Header.Clone()}\n}\n\nfunc parseRetryAfter(value string, now time.Time) time.Duration {\n\tvalue = strings.TrimSpace(value)\n\tif value == \"\" {\n\t\treturn 0\n\t}\n\tif seconds, err := strconv.Atoi(value); err == nil {\n\t\tif seconds <= 0 {\n\t\t\treturn 0\n\t\t}\n\t\treturn time.Duration(seconds) * time.Second\n\t}\n\twhen, err := http.ParseTime(value)\n\tif err != nil {\n\t\treturn 0","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/retry.go#L39-L75","documentation":"NewHTTPError builds an HTTPError from an *http.Response, but if the response pointer is nil there is no status, header, or body to expose. Rather than panicking on a nil dereference, it returns this plain error indicating the API call produced no response at all (e.g. transport failure, client error, or a bug passing nil).","triggerScenarios":"callAPI or Stream completing with resp == nil (connection failure before a response, or an error path passing nil into NewHTTPError).","commonSituations":"Network/DNS failures or context cancellation causing http.Client.Do to return nil response with a non-nil error; custom transports returning (nil, nil); mis-wired HTTP clients.","solutions":["Check and handle the transport error from the HTTP call before treating the response as valid — a nil response usually accompanies a non-nil error","Ensure any custom http.Client/Transport/RoundTripper never returns (nil, nil)","Verify network connectivity, proxy settings, and that the request actually reached the server"],"exampleFix":"// before\nresp, _ := client.Do(req)\nreturn NewHTTPError(resp, body)\n// after\nresp, err := client.Do(req)\nif err != nil {\n    return fmt.Errorf(\"request failed: %w\", err)\n}\nif resp == nil {\n    return errors.New(\"API error: nil response\")\n}","handlingStrategy":"try-catch","validationCode":"resp, err := client.Do(req)\nif err != nil { return fmt.Errorf(\"transport: %w\", err) }\nif resp == nil { return errors.New(\"no response from API\") }","typeGuard":"func hasResponse(resp *http.Response) bool { return resp != nil }","tryCatchPattern":"err := doCall()\nvar httpErr *ai.HTTPError\nif err != nil && !strings.Contains(err.Error(), \"nil response\") {\n    if errors.As(err, &httpErr) { /* handle status/retry-after */ }\n}","preventionTips":["Never discard the error from http.Client.Do; nil response almost always accompanies an error","Ensure custom RoundTrippers return (response, error) correctly — never (nil, nil)","Handle ctx cancellation and network failures distinctly from HTTP status errors"],"tags":["go","http","network","nil-pointer"],"backgroundTag":"nil-response","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}