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
- Classify the wrapped error first: 401/403 means token problem, timeout/DNS means network problem
- Test the token directly: curl -H "Authorization: Bearer $TOKEN" https://api.github.com/user
- Verify GITHUB_HOST is a full https:// origin reachable from the server process
- 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
- Alert on 401-wrapped viewer-login failures so expired tokens are caught early
- Prefer user-scoped tokens for lockdown deployments
- Keep GITHUB_HOST a full https origin and monitor its reachability
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
- failed to check lockdown mode: %w
- viewer login returned empty
- owner is required
- failed to get GitHub client: %w
- failed to query repository metadata: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/a3e69756a630c856.
Report an issue: GitHub.