glanceapp/glance · error
%d %s
Error message
%d %s
What it means
Returned by the custom API response handler when the HTTP status is outside 200-299 and the body is not valid JSON: fmt.Errorf("%d %s", resp.StatusCode, http.StatusText(resp.StatusCode)) yields messages like "502 Bad Gateway" or "401 Unauthorized". On 2xx statuses invalid JSON produces a different error ("invalid response JSON"), so this format specifically means non-2xx + non-JSON body.
Source
Thrown at internal/glance/widget-custom-api.go:268
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
body := strings.TrimSpace(string(bodyBytes))
if !req.SkipJSONValidation && body != "" && !gjson.Valid(body) {
if 200 <= resp.StatusCode && resp.StatusCode < 300 {
truncatedBody, isTruncated := limitStringLength(body, 100)
if isTruncated {
truncatedBody += "... <truncated>"
}
slog.Error("Invalid response JSON in custom API widget", "url", req.httpRequest.URL.String(), "body", truncatedBody)
return nil, errors.New("invalid response JSON")
}
return nil, fmt.Errorf("%d %s", resp.StatusCode, http.StatusText(resp.StatusCode))
}
return &customAPIResponseData{
JSON: decoratedGJSONResult{gjson.Parse(body)},
Response: resp,
}, nil
}
func fetchAndRenderCustomAPIRequest(
primaryReq *CustomAPIRequest,
subReqs map[string]*CustomAPIRequest,
options customAPIOptions,
tmpl *template.Template,
) (template.HTML, error) {
var primaryData *customAPIResponseData
subData := make(map[string]*customAPIResponseData, len(subReqs))
var err errorView on GitHub (pinned to 91324e8de7)
Solutions
- curl the exact URL with the same headers from the widget config and inspect the status code and body.
- Fix auth: add/refresh the API key or token header the endpoint expects.
- Correct the URL/path (404) or scheme/host (502).
- If the endpoint legitimately returns non-JSON error bodies on failure, consider options that tolerate it (e.g. skip JSON validation) or accept the widget showing the error status.
Defensive patterns
Strategy: try-catch
Try / catch
data, err := executeCustomAPIRequest(req)
if err != nil {
if strings.Contains(err.Error(), "invalid response JSON") {
// 2xx but bad JSON: log body sample, likely API contract change
} else {
// "NNN Status Text": HTTP-level failure — auth, proxy, or wrong URL
}
return nil, err
} Prevention
- Verify endpoints with curl (same URL + headers) before adding them to config.
- Keep API keys current; expired keys commonly produce HTML auth pages.
- Prefer JSON-returning endpoints; HTML error pages from proxies are the usual trigger.
When it happens
Trigger: Any custom-api request (primary or subrequest) whose endpoint returns e.g. 502/503 from a reverse proxy HTML error page, 401/403 from an auth wall returning HTML, or 404 for a wrong URL path.
Common situations: Expired API key so the gateway returns an HTML login page; wrong URL or path segment; upstream service down and the proxy's error page is HTML; Cloudflare challenge pages.
Related errors
- missing API token
- failed to retrieve any content
- expected status code %d, got %d
- could not fetch list of watch UUIDs: %v
- fetching session ID: %v
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/0312690ca87dc0d2.
Report an issue: GitHub.