github/github-mcp-server · error

failed to query viewer login: %w

Error message

failed to query viewer login: %w

What it means

The lockdown RepoAccessCache lazily runs the GraphQL query `viewer { login }` with the request's token the first time a lockdown safety check needs the viewer identity (getViewerLogin via viewerLoginFor). Any failure of that query - transport, authentication, rate limiting, wrong endpoint - is wrapped with this message. Note the cache memoizes the login, so the query runs once per cache instance, not per tool call.

Source

Thrown at pkg/lockdown/lockdown.go:156

	return viewerLogin == strings.ToLower(username), nil
}

func (c *RepoAccessCache) viewerLoginFor(ctx context.Context) (string, error) {
	c.viewerMu.Lock()
	defer c.viewerMu.Unlock()
	if c.viewerLogin != "" {
		return c.viewerLogin, nil
	}
	if c.client == nil {
		return "", fmt.Errorf("nil GraphQL client")
	}
	var query struct {
		Viewer struct {
			Login githubv4.String
		}
	}
	if err := c.client.Query(ctx, &query, nil); err != nil {
		return "", fmt.Errorf("failed to query viewer login: %w", err)
	}
	login := strings.ToLower(string(query.Viewer.Login))
	if login == "" {
		return "", fmt.Errorf("viewer login returned empty")
	}
	c.viewerLogin = login
	return c.viewerLogin, nil
}

// setViewerLogin seeds the cached viewer login from a piggy-backed query response.
func (c *RepoAccessCache) setViewerLogin(login string) {
	if login == "" {
		return
	}
	c.viewerMu.Lock()
	defer c.viewerMu.Unlock()
	if c.viewerLogin == "" {
		c.viewerLogin = strings.ToLower(login)

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Classify the wrapped error first: 401/403 means token problem, timeout/DNS means network problem
  2. Test the token directly: curl -H "Authorization: Bearer $TOKEN" https://api.github.com/user
  3. Verify GITHUB_HOST is a full https:// origin reachable from the server process
  4. If rate-limited, back off and let the next request repopulate the cache
Defensive patterns

Strategy: retry

Validate before calling

// preflight: prove the token can read its own user before enabling lockdown
req, _ := http.NewRequest(http.MethodGet, apiBase+"/user", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil || resp.StatusCode != http.StatusOK {
	return errors.New("token cannot query viewer; lockdown login lookups will fail")
}

Try / catch

if _, err := cache.IsSafeContent(ctx, user, owner, repo); err != nil {
	if strings.Contains(err.Error(), "failed to query viewer login") {
		// unwrap: 401/403 -> fix the token (no retry); timeout/DNS -> retry with backoff
	}
}

Prevention

When it happens

Trigger: First lockdown check (IsSafeContent) on a request whose token cannot complete the Viewer query: expired/revoked PAT (401), GITHUB_HOST pointing at the wrong or unreachable endpoint, DNS/proxy failure, or a secondary rate limit (403).

Common situations: Long-lived deployments with rotating tokens that silently expire; GHES hosts configured without a scheme or with an untrusted self-signed cert; egress firewalls blocking the API host.

Related errors


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/a3e69756a630c856. Report an issue: GitHub.