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

  1. Check if a newer Glance release fixes the Twitch persisted query hash and upgrade (this error usually means the internal Twitch API contract drifted).
  2. Run `glance diagnose` and manually test connectivity to maestro.gql.twitch.com from the host (proxy/firewall can rewrite responses).
  3. Retry after a few minutes to rule out a transient Twitch-side empty response; the widget caches 10 minutes.
  4. If persistent, temporarily remove or comment out the twitch-top-games widget so the rest of the dashboard renders.
  5. 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

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


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