github/github-mcp-server · error

viewer login returned empty

Error message

viewer login returned empty

What it means

The Viewer GraphQL query succeeded (HTTP 200) but returned an empty login, so the RepoAccessCache refuses to continue - lockdown's comparisons (viewer == content author, per IsSafeContent) are meaningless without a login. This is the signature of tokens with no user context, primarily GitHub App server-to-server installation tokens (ghs_) whose viewer is null.

Source

Thrown at pkg/lockdown/lockdown.go:160

	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)
	}
}

func (c *RepoAccessCache) getRepoAccessInfo(ctx context.Context, username, owner, repo string) (RepoAccessInfo, error) {

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Switch the deployment to a user-scoped token: classic PAT (ghp_), fine-grained PAT (github_pat_), or user-to-server app token (ghu_)
  2. If machine tokens are mandatory, disable lockdown mode for that deployment
  3. Confirm the token has a viewer: curl -H "Authorization: Bearer $TOKEN" https://api.github.com/user must return a non-empty login
Defensive patterns

Strategy: validation

Validate before calling

func hasUserContext(token string) bool {
	// ghs_ = server-to-server installation token: viewer.login is null
	return !strings.HasPrefix(token, "ghs_")
}
if lockdownEnabled && !hasUserContext(token) {
	return errors.New("lockdown requires a user-scoped token; ghs_ tokens have no viewer")
}

Prevention

When it happens

Trigger: Lockdown mode enabled while the request authenticates with a ghs_ installation token or any credential whose viewer.login resolves to null/empty; setViewerLogin also refuses to seed an empty value from piggy-backed responses.

Common situations: Migrating a deployment from PATs to a GitHub App (server-to-server) without disabling lockdown; machine credentials used where per-user identity is required.

Related errors


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