{"record":{"id":"4e2d7f5ccdcdc1e6","repo":"github/github-mcp-server","slug":"failed-to-check-lockdown-mode-w","errorCode":null,"errorMessage":"failed to check lockdown mode: %w","messagePattern":"failed to check lockdown mode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/pullrequests.go","lineNumber":541,"sourceCode":"\t}\n\n\t// Lockdown mode filtering\n\tif ff.LockdownMode {\n\t\tif cache == nil {\n\t\t\treturn nil, fmt.Errorf(\"lockdown cache is not configured\")\n\t\t}\n\n\t\t// Iterate through threads and filter comments\n\t\tfor i := range query.Repository.PullRequest.ReviewThreads.Nodes {\n\t\t\tthread := &query.Repository.PullRequest.ReviewThreads.Nodes[i]\n\t\t\tfilteredComments := make([]reviewCommentNode, 0, len(thread.Comments.Nodes))\n\n\t\t\tfor _, comment := range thread.Comments.Nodes {\n\t\t\t\tlogin := string(comment.Author.Login)\n\t\t\t\tif login != \"\" {\n\t\t\t\t\tisSafeContent, err := cache.IsSafeContent(ctx, login, owner, repo)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn nil, fmt.Errorf(\"failed to check lockdown mode: %w\", err)\n\t\t\t\t\t}\n\t\t\t\t\tif isSafeContent {\n\t\t\t\t\t\tfilteredComments = append(filteredComments, comment)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthread.Comments.Nodes = filteredComments\n\t\t\tthread.Comments.TotalCount = githubv4.Int(int32(len(filteredComments))) //nolint:gosec // comment count is bounded by API limits\n\t\t}\n\t}\n\n\treturn MarshalledTextResult(convertToMinimalReviewThreadsResponse(query)), nil\n}\n\nfunc GetPullRequestReviews(ctx context.Context, client *github.Client, deps ToolDependencies, owner, repo string, pullNumber int, pagination PaginationParams) (*mcp.CallToolResult, error) {\n\tcache, err := deps.GetRepoAccessCache(ctx)\n\tif err != nil {","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/pullrequests.go#L523-L559","documentation":"While get_pull_request_review_comments filters review threads under lockdown mode, each comment author is checked with cache.IsSafeContent (pkg/lockdown/lockdown.go). That method queries GraphQL for the author's repo access and the viewer login; any of those failing (network error, GraphQL error, empty viewer login, nil client) is wrapped as 'failed to check lockdown mode'.","triggerScenarios":"IsSafeContent's getRepoAccessInfo GraphQL query fails (expired token, GITHUB_GRAPHQL_URL pointing at a broken endpoint, 502 from GraphQL), or viewerLoginFor fails with 'failed to query viewer login' / 'viewer login returned empty' (token without GraphQL access, GHES GraphQL disabled), or the cache was built with a nil GraphQL client.","commonSituations":"Classic PATs work for REST but the GraphQL endpoint is blocked by egress policy; GHES deployments where /api/graphql requires separate enablement; tokens expiring mid-session during long comment-listing runs; network blips during per-comment fan-out.","solutions":["Read the wrapped cause — it distinguishes GraphQL transport failures from viewer-login problems","Verify the token can query GraphQL: a Viewer { login } query with the same credentials","Check GITHUB_GRAPHQL_URL / GHES GraphQL availability and egress rules","Retry the tool call — transient GraphQL 502s are common; the access cache also caches results so retries are cheaper"],"exampleFix":"// before\nisSafeContent, err := cache.IsSafeContent(ctx, login, owner, repo)\nif err != nil {\n\treturn nil, fmt.Errorf(\"failed to check lockdown mode: %w\", err)\n}\n\n// after — keep the author context for actionable failures\nisSafeContent, err := cache.IsSafeContent(ctx, login, owner, repo)\nif err != nil {\n\treturn nil, fmt.Errorf(\"lockdown check failed for author %s on %s/%s: %w\", login, owner, repo, err)\n}","handlingStrategy":"retry","validationCode":"// Pre-flight: prove GraphQL works with this token before lockdown-filtered tools\nvar q struct{ Viewer struct{ Login githubv4.String } }\nif err := gqlClient.Query(ctx, &q, nil); err != nil {\n\treturn fmt.Errorf(\"GraphQL unavailable for lockdown checks: %w\", err)\n}","typeGuard":"func isGraphQLTransient(err error) bool {\n\tmsg := err.Error()\n\treturn strings.Contains(msg, \"502\") || strings.Contains(msg, \"connection reset\") ||\n\t\tstrings.Contains(msg, \"EOF\")\n}","tryCatchPattern":"isSafe, err := cache.IsSafeContent(ctx, login, owner, repo)\nif err != nil {\n\tif isGraphQLTransient(err) {\n\t\tisSafe, err = cache.IsSafeContent(ctx, login, owner, repo) // cache makes retry cheap\n\t}\n}\nif err != nil {\n\treturn nil, fmt.Errorf(\"failed to check lockdown mode: %w\", err)\n}","preventionTips":["Smoke-test the Viewer query at startup when lockdown mode is on","Ensure egress allows the GraphQL endpoint, not just REST","Expire/refresh tokens before long sessions; IsSafeContent failures spike with expired tokens"],"tags":["go","mcp","lockdown-mode","graphql","authentication","network"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}