glanceapp/glance · error
no categories could be retrieved
Error message
no categories could be retrieved
What it means
Thrown by fetchTopGamesFromTwitch when the Twitch GQL endpoint (maestro.gql.twitch.com) returns HTTP 200 with a JSON body that decodes to an empty array. Glance queries Twitch's internal persisted-query GraphQL API with a hardcoded sha256Hash; if Twitch changes/retires that persisted query or the response shape, the outer array decodes but is empty, so no categories can be extracted. It is a data-shape/empty-response error, not a transport error (transport errors return earlier from decodeJsonFromRequest).
Source
Thrown at internal/glance/widget-twitch-top-games.go:91
} `json:"directoriesWithTags"`
} `json:"data"`
}
const twitchDirectoriesOperationRequestBody = `[
{"operationName": "BrowsePage_AllDirectories","variables": {"limit": %d,"options": {"sort": "VIEWER_COUNT","tags": []}},"extensions": {"persistedQuery": {"version": 1,"sha256Hash": "2f67f71ba89f3c0ed26a141ec00da1defecb2303595f5cda4298169549783d9e"}}}
]`
func fetchTopGamesFromTwitch(exclude []string, limit int) ([]twitchCategory, error) {
reader := strings.NewReader(fmt.Sprintf(twitchDirectoriesOperationRequestBody, len(exclude)+limit))
request, _ := http.NewRequest("POST", twitchGqlEndpoint, reader)
request.Header.Add("Client-ID", twitchGqlClientId)
response, err := decodeJsonFromRequest[[]twitchDirectoriesOperationResponse](defaultHTTPClient, request)
if err != nil {
return nil, err
}
if len(response) == 0 {
return nil, errors.New("no categories could be retrieved")
}
edges := (response)[0].Data.DirectoriesWithTags.Edges
categories := make([]twitchCategory, 0, len(edges))
for i := range edges {
if slices.Contains(exclude, edges[i].Node.Slug) {
continue
}
category := &edges[i].Node
category.AvatarUrl = strings.Replace(category.AvatarUrl, "285x380", "144x192", 1)
if len(category.Tags) > 2 {
category.Tags = category.Tags[:2]
}
gameReleasedDate, err := time.Parse("2006-01-02T15:04:05Z", category.GameReleaseDate)View on GitHub (pinned to 91324e8de7)
Solutions
- Check if a newer Glance release fixes the Twitch persisted query hash and upgrade (this error usually means the internal Twitch API contract drifted).
- Run `glance diagnose` and manually test connectivity to maestro.gql.twitch.com from the host (proxy/firewall can rewrite responses).
- Retry after a few minutes to rule out a transient Twitch-side empty response; the widget caches 10 minutes.
- If persistent, temporarily remove or comment out the twitch-top-games widget so the rest of the dashboard renders.
- If developing locally, POST the twitchDirectoriesOperationRequestBody to the endpoint with curl and inspect the body to confirm whether data.directoriesWithTags.edges is present.
Defensive patterns
Strategy: retry
Try / catch
// In a custom build calling fetchTopGamesFromTwitch indirectly via the widget:
// no direct API; treat any update error shown on the widget as transient first.
if err != nil {
if strings.Contains(err.Error(), "no categories could be retrieved") {
// transient or upstream contract drift: wait for next cached update,
// check for a newer Glance release
}
} Prevention
- Pin a recent Glance version so the Twitch persisted-query hash stays current.
- Monitor the Glance repo issues for 'twitch' breakage reports after Twitch API changes.
- Keep the widget's exclude/limit within sane bounds so the requested batch size stays valid.
When it happens
Trigger: POST to twitchGqlEndpoint with the BrowsePage_AllDirectories persisted query returns a JSON array of length 0 (e.g. Twitch returns [] or an errors-only payload that unmarshals to zero elements); happens when the hardcoded sha256Hash 2f67f71b... is revoked, when Twitch's GQL gateway behaves differently, or during transient Twitch-side anomalies that still yield 200 with an empty batch response.
Common situations: A Glance version upgrade is needed after Twitch rotated its persisted query hash; running an old Glance image; intermittent Twitch GQL behavior behind rate limiting or regional gateways; corporate proxies returning 200 with rewritten bodies.
Related errors
- expected 2 operation responses, got %d
- unmarshalling channel shell: %w
- unmarshalling stream metadata: %w
- unknown operation name: %s
- %w: failed to fetch %d channels
AI-assisted analysis of glanceapp/glance@91324e8de7 (2026-08-15).
Data as JSON: /api/errors/31a4693c7d78ba53.
Report an issue: GitHub.