{"record":{"id":"d198606a8eccb015","repo":"wtfutil/wtf","slug":"s-d19860","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/gitter/client.go","lineNumber":72,"sourceCode":"\nfunc apiRequest(path, apiToken string) (*http.Response, error) {\n\treq, err := http.NewRequest(\"GET\", apiBaseURL+path, http.NoBody)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tbearer := fmt.Sprintf(\"Bearer %s\", apiToken)\n\treq.Header.Add(\"Authorization\", bearer)\n\n\thttpClient := &http.Client{}\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode < 200 || resp.StatusCode > 299 {\n\t\treturn nil, fmt.Errorf(\"%s\", resp.Status)\n\t}\n\n\treturn resp, nil\n}\n","sourceCodeStart":54,"sourceCodeEnd":77,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/gitter/client.go#L54-L77","documentation":"gitter's apiRequest returns an error formatted from resp.Status (e.g., \"401 Unauthorized\") when the Gitter API responds outside 2xx. Unlike some clients it surfaces the HTTP status line rather than a custom message, so the exact reason is readable. Callers GetMessages and GetRoom both fail through this path.","triggerScenarios":"Any non-2xx from Gitter's REST API: missing/revoked bearer token (401), room not found or no access (403/404), rate limiting (429), or Gitter-side 5xx. Note Gitter itself was deprecated/migrated to Matrix, so endpoint-level 4xx/5xx are increasingly common.","commonSituations":"Expired Gitter token after the Matrix migration, deleted or renamed rooms, token scoped to another account, or hitting API rate limits during polling.","solutions":["Read resp.Status in the error: 401/403 means regenerate the API token in settings.","Verify the room URI/ID passed to GetRoom still exists (rooms were renamed during Gitter's migration).","Back off on 429 and reduce polling frequency.","If Gitter endpoints are permanently gone, migrate the module to the Matrix/Gitter bridge API."],"exampleFix":"// before\nif resp.StatusCode < 200 || resp.StatusCode > 299 {\n\treturn nil, fmt.Errorf(\"%s\", resp.Status)\n}\n// after\nif resp.StatusCode < 200 || resp.StatusCode > 299 {\n\treturn nil, fmt.Errorf(\"gitter api request failed: %s\", resp.Status)\n}","handlingStrategy":"try-catch","validationCode":"if token == \"\" {\n\treturn fmt.Errorf(\"gitter token missing — set it in widget settings\")\n}","typeGuard":"func isAuthFailure(statusLine string) bool {\n\treturn strings.HasPrefix(statusLine, \"401\") || strings.HasPrefix(statusLine, \"403\")\n}","tryCatchPattern":"resp, err := apiRequest(req)\nif err != nil {\n\tif isAuthFailure(err.Error()) {\n\t\tlog.Printf(\"gitter auth failed (%v): regenerate token\", err)\n\t\treturn\n\t}\n\tlog.Printf(\"gitter request failed: %v\", err)\n\treturn\n}","preventionTips":["Regenerate the Gitter/Matrix token periodically and after account changes.","Verify room URIs still exist — Gitter rooms migrated to Matrix and many were renamed.","Add exponential backoff around apiRequest for 429/5xx responses."],"tags":["http","api","auth","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"}