{"record":{"id":"7ecb8973374d785b","repo":"micro/go-micro","slug":"api-error-s-s","errorCode":null,"errorMessage":"API error (%s): %s","messagePattern":"API error \\((.+?)\\): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ai/atlascloud/atlascloud.go","lineNumber":964,"sourceCode":"\t}\n\n\tapiURL := strings.TrimRight(p.opts.BaseURL, \"/\") + \"/api/v1/model/generateImage\"\n\thttpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(reqBody))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\thttpReq.Header.Set(\"Authorization\", \"Bearer \"+p.opts.APIKey)\n\n\thttpResp, err := http.DefaultClient.Do(httpReq)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"API request failed: %w\", err)\n\t}\n\tdefer httpResp.Body.Close()\n\n\trespBody, _ := io.ReadAll(httpResp.Body)\n\tif httpResp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"API error (%s): %s\", httpResp.Status, string(respBody))\n\t}\n\n\tvar submitResp struct {\n\t\tCode int    `json:\"code\"`\n\t\tMsg  string `json:\"message\"`\n\t\tData struct {\n\t\t\tID     string `json:\"id\"`\n\t\t\tStatus string `json:\"status\"`\n\t\t} `json:\"data\"`\n\t}\n\tif err := json.Unmarshal(respBody, &submitResp); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse submit response: %w\", err)\n\t}\n\tif submitResp.Code != 200 {\n\t\treturn nil, fmt.Errorf(\"API error: %s\", submitResp.Msg)\n\t}\n\n\tpredictionID := submitResp.Data.ID","sourceCodeStart":946,"sourceCodeEnd":982,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/ai/atlascloud/atlascloud.go#L946-L982","documentation":"GenerateImage throws this when the submit response arrives with a non-200 HTTP status. It embeds the HTTP status line and the raw response body so the caller can see exactly what the AtlasCloud API rejected. Unlike the chat path, there is no retry/RateLimit handling here — the error is returned immediately.","triggerScenarios":"httpResp.StatusCode != http.StatusOK on the generateImage submit call: 401 (bad API key), 403, 404 (wrong path/BaseURL), 429 (rate limited), or 5xx from the provider.","commonSituations":"Expired or missing ATLASCLOUD API key, wrong BaseURL pointing at a non-image endpoint, exceeding image-generation quotas, or provider outage returning 502/503 through a load balancer.","solutions":["Read the embedded body in the error — it contains the API's JSON error message identifying the cause.","For 401/403, verify and rotate the API key (Authorization: Bearer p.opts.APIKey).","For 429, back off and retry later; check your AtlasCloud quota/plan.","For 404, confirm BaseURL and that the /api/v1/model/generateImage path exists for your API version."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if apiKey == \"\" {\n    return fmt.Errorf(\"ATLASCLOUD_API_KEY is not set\")\n}","typeGuard":null,"tryCatchPattern":"img, err := provider.GenerateImage(ctx, req)\nif err != nil {\n    var apiErr *AIError // or match on \"API error (\"\n    if strings.Contains(err.Error(), \"API error (401\") || strings.Contains(err.Error(), \"API error (403\") {\n        return fmt.Errorf(\"check AtlasCloud API key: %w\", err)\n    }\n    if strings.Contains(err.Error(), \"API error (429\") {\n        // backoff and retry later\n    }\n    return err\n}","preventionTips":["Check the HTTP status and embedded body in the error before deciding how to respond.","Rotate and validate the API key before deploy; 401 means credentials, not code.","Track quota usage to anticipate 429s and back off proactively.","Alert on 5xx bursts — they indicate provider outages, not caller bugs."],"tags":["http-status","authentication","rate-limit","go","atlascloud"],"backgroundTag":"http-api-error-response","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}