{"record":{"id":"154b2bea835a2ed6","repo":"wtfutil/wtf","slug":"unexpected-status-d-from-dev-to-api","errorCode":null,"errorMessage":"unexpected status %d from DEV.to API","messagePattern":"unexpected status (.+?) from DEV\\.to API","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/devto/client.go","lineNumber":74,"sourceCode":"\t}\n\tif perPage > 0 {\n\t\tq.Set(\"per_page\", fmt.Sprintf(\"%d\", perPage))\n\t}\n\tu.RawQuery = q.Encode()\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"creating request: %w\", err)\n\t}\n\n\tresp, err := c.httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"executing request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"unexpected status %d from DEV.to API\", resp.StatusCode)\n\t}\n\n\tvar articles []Article\n\tif err := json.NewDecoder(resp.Body).Decode(&articles); err != nil {\n\t\treturn nil, fmt.Errorf(\"decoding response: %w\", err)\n\t}\n\n\treturn articles, nil\n}\n","sourceCodeStart":56,"sourceCodeEnd":84,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/devto/client.go#L56-L84","documentation":"FetchArticles in modules/devto/client.go only accepts HTTP 200 from the DEV.to /articles endpoint; any other status (401, 403, 422, 429, 5xx) is rejected with this message. The library does not inspect the body on failure, so the status code is the only diagnostic returned. It wraps nothing — the raw status number is interpolated into the message.","triggerScenarios":"Any non-200 response from the DEV.to API during FetchArticles: missing/invalid api-key header (401/403), malformed query params like page or tag (422), rate limiting (429), or DEV.to server errors (500/502/503).","commonSituations":"Expired or unset DEV_TO_API_KEY, hitting DEV.to's rate limit during frequent refreshes, transient DEV.to outages, or proxy/gateway returning an HTML error page with a non-200 status.","solutions":["Verify the API key passed to the client is set and valid (curl -H 'api-key: ...' https://dev.to/api/articles/me).","Log the full status code; if 429, back off and increase the widget refresh interval.","If 422, check the query parameters built into the request URL for invalid values.","If 5xx, retry later — the failure is server-side, not a client bug."],"exampleFix":"// before\nif resp.StatusCode != http.StatusOK {\n\treturn nil, fmt.Errorf(\"unexpected status %d from DEV.to API\", resp.StatusCode)\n}\n// after\nif resp.StatusCode != http.StatusOK {\n\tbody, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\n\treturn nil, fmt.Errorf(\"unexpected status %d from DEV.to API: %s\", resp.StatusCode, body)\n}","handlingStrategy":"try-catch","validationCode":"// Go: validate config before calling\nif apiKey == \"\" {\n\treturn fmt.Errorf(\"DEV.to API key is not configured\")\n}","typeGuard":"func isStatusError(err error) (int, bool) {\n\tmsg := err.Error()\n\tvar code int\n\tif _, e := fmt.Sscanf(msg, \"unexpected status %d from DEV.to API\", &code); e == nil {\n\t\treturn code, true\n\t}\n\treturn 0, false\n}","tryCatchPattern":"articles, err := client.FetchArticles(ctx)\nif err != nil {\n\tvar code int\n\tif fmt.Sscanf(err.Error(), \"unexpected status %d from DEV.to API\", &code) == nil && code == http.StatusTooManyRequests {\n\t\ttime.Sleep(backoff) // retry later\n\t\treturn\n\t}\n\tlog.Printf(\"devto fetch failed: %v\", err)\n\treturn\n}","preventionTips":["Keep the DEV.to API key in env/config and verify it with a curl call before wiring it in.","Set a refresh interval well above DEV.to rate limits.","Log status codes so 429 vs 401 vs 5xx are distinguishable in production."],"tags":["http","api","network","go"],"backgroundTag":"http-non-200-response","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}