glanceapp/glance · error
unexpected status code %d from %s, response: %s
Error message
unexpected status code %d from %s, response: %s
What it means
Generic helper (decodeJsonFromRequest) that performs a GET and decodes JSON: the response status was not 200, so it reports the code, the request URL, and up to 256 bytes of the body. It is the primary network/API error surfaced by many widgets (markets, weather geocoding, Twitch alternatives, etc.).
Source
Thrown at internal/glance/widget-utils.go:79
func decodeJsonFromRequest[T any](client requestDoer, request *http.Request) (T, error) {
var result T
response, err := client.Do(request)
if err != nil {
return result, err
}
defer response.Body.Close()
body, err := io.ReadAll(response.Body)
if err != nil {
return result, err
}
if response.StatusCode != http.StatusOK {
truncatedBody, _ := limitStringLength(string(body), 256)
return result, fmt.Errorf(
"unexpected status code %d from %s, response: %s",
response.StatusCode,
request.URL,
truncatedBody,
)
}
err = json.Unmarshal(body, &result)
if err != nil {
return result, err
}
return result, nil
}
func decodeJsonFromRequestTask[T any](client requestDoer) func(*http.Request) (T, error) {
return func(request *http.Request) (T, error) {
return decodeJsonFromRequest[T](client, request)View on GitHub (pinned to 91324e8de7)
Solutions
- Read the truncated response body in the message — it usually names the exact cause (invalid key, quota exceeded, etc.)
- Fix the credential/site config for the widget that failed (check its docs for token fields)
- Raise the widget's cache duration to reduce request frequency if the status is 429
- Retry later or check the upstream service's status page for 5xx
Defensive patterns
Strategy: retry
Validate before calling
// Verify the endpoint is reachable and returns 200 before the widget calls it
resp, err := http.Get(apiURL) // in a preflight or healthcheck
if err == nil {
defer resp.Body.Close()
_ = resp.StatusCode // act on non-200 before relying on the API
} Type guard
func isUnexpectedStatus(err error) bool {
return err != nil && strings.Contains(err.Error(), "unexpected status code")
} Try / catch
data, err := decodeJsonFromRequest[ T ](client, req)
if err != nil {
if isUnexpectedStatus(err) {
// parse the code from the message; back off on 429, surface 401/403 as config problems
slog.Warn("upstream API error", "err", err)
return retryWithBackoff(...) // for 429/5xx only
}
return err
} Prevention
- Configure required API keys for widgets before enabling them
- Set per-widget cache times so refresh frequency stays under rate limits
- Monitor the truncated response body — upstream error messages identify key/quota issues immediately
When it happens
Trigger: Any upstream JSON API returning 4xx/5xx: 401/403 for missing or bad API keys, 429 for rate limits, 404 for a wrong feed URL, 5xx outages, or a captive portal returning 200-less HTML.
Common situations: Expired or absent API token for a widget that requires one; aggressive refresh (low cache settings) hitting rate limits; upstream maintenance; DNS/proxy returning error pages.
Related errors
- could not solve reddit challenge
- failed to retrieve any content
- expected status code %d, got %d
- %d %s
- parsing authentication response: %v
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/91c44f011ca1101f.
Report an issue: GitHub.