wtfutil/wtf · error

%s

Error message

%s

What it means

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.

Source

Thrown at modules/gitter/client.go:72

func apiRequest(path, apiToken string) (*http.Response, error) {
	req, err := http.NewRequest("GET", apiBaseURL+path, http.NoBody)
	if err != nil {
		return nil, err
	}

	bearer := fmt.Sprintf("Bearer %s", apiToken)
	req.Header.Add("Authorization", bearer)

	httpClient := &http.Client{}
	resp, err := httpClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer func() { _ = resp.Body.Close() }()

	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		return nil, fmt.Errorf("%s", resp.Status)
	}

	return resp, nil
}

View on GitHub (pinned to bb838c1ccb)

Solutions

  1. Read resp.Status in the error: 401/403 means regenerate the API token in settings.
  2. Verify the room URI/ID passed to GetRoom still exists (rooms were renamed during Gitter's migration).
  3. Back off on 429 and reduce polling frequency.
  4. If Gitter endpoints are permanently gone, migrate the module to the Matrix/Gitter bridge API.

Example fix

// before
if resp.StatusCode < 200 || resp.StatusCode > 299 {
	return nil, fmt.Errorf("%s", resp.Status)
}
// after
if resp.StatusCode < 200 || resp.StatusCode > 299 {
	return nil, fmt.Errorf("gitter api request failed: %s", resp.Status)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if token == "" {
	return fmt.Errorf("gitter token missing — set it in widget settings")
}

Type guard

func isAuthFailure(statusLine string) bool {
	return strings.HasPrefix(statusLine, "401") || strings.HasPrefix(statusLine, "403")
}

Try / catch

resp, err := apiRequest(req)
if err != nil {
	if isAuthFailure(err.Error()) {
		log.Printf("gitter auth failed (%v): regenerate token", err)
		return
	}
	log.Printf("gitter request failed: %v", err)
	return
}

Prevention

When it happens

Trigger: 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.

Common situations: Expired Gitter token after the Matrix migration, deleted or renamed rooms, token scoped to another account, or hitting API rate limits during polling.

Related errors


AI-assisted analysis of wtfutil/wtf@bb838c1ccb (2026-09-03). Data as JSON: /api/errors/d198606a8eccb015. Report an issue: GitHub.