glanceapp/glance · error

unexpected status code %d for %s, response: %s

Error message

unexpected status code %d for %s, response: %s

What it means

The XML twin of the JSON helper (decodeXmlFromRequest): status was not 200, and the error includes the status code, URL, and a 256-byte body snippet. Used for RSS/Atom-style feeds such as the videos widget's YouTube feeds.

Source

Thrown at internal/glance/widget-utils.go:119

// TODO: tidy up, these are a copy of the above but with a line changed
func decodeXmlFromRequest[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 for %s, response: %s",
			response.StatusCode,
			request.URL,
			truncatedBody,
		)
	}

	err = xml.Unmarshal(body, &result)
	if err != nil {
		return result, err
	}

	return result, nil
}

func decodeXmlFromRequestTask[T any](client requestDoer) func(*http.Request) (T, error) {
	return func(request *http.Request) (T, error) {
		return decodeXmlFromRequest[T](client, request)

View on GitHub (pinned to 91324e8de7)

Solutions

  1. Inspect the status code and body snippet: 404 means a bad/deleted channel or playlist ID, 429 means back off
  2. Correct the channel/playlist IDs in the videos widget configuration
  3. Increase the widget's cache time so feeds are fetched less often
Defensive patterns

Strategy: retry

Type guard

func isUnexpectedStatus(err error) bool {
	return err != nil && strings.Contains(err.Error(), "unexpected status code")
}

Try / catch

feed, err := decodeXmlFromRequest[ T ](client, req)
if err != nil && isUnexpectedStatus(err) {
    // 404: drop the bad feed from config; 429/5xx: retry with backoff
    slog.Warn("feed fetch failed", "url", req.URL.String(), "err", err)
}

Prevention

When it happens

Trigger: A feed URL returning non-200: 404 for a deleted channel/playlist ID, 429 from YouTube feed throttling, 403 from an IP block, or 5xx from the feed host.

Common situations: A YouTube channel ID in the videos config is wrong or the channel was removed; a self-hosted RSS host blocks the server's IP; too frequent polling of the same feeds.

Related errors


AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15). Data as JSON: /api/errors/fb7048efbce0a29b. Report an issue: GitHub.