fix(github): org repo listing fails with fine-grained PATs lacking Issues:Read#415
Merged
Merged
Conversation
59ef410 to
a5c4075
Compare
a5c4075 to
445ac10
Compare
…sues:Read
Root cause: `issues { totalCount }` is typed `Int!` in GitHub's GraphQL schema.
When a FGPAT lacks Issues:Read on private repos, GitHub cannot resolve that
non-null field and nulls out the entire repo node — silently dropping those
repos from the batch and surfacing the error as a full batch failure.
Fix: move issues fetching into a dedicated `issueNodes: repositories(...)`
alias within the same GraphQL query. The main `repositories` selection no
longer includes `issues`, so all repos are always returned regardless of
Issues:Read permission. The shurcooL/graphql library unmarshals response data
before returning errors, so when issueNodes gets FORBIDDEN the main repo list
is already intact.
- isIssuesPermissionError() detects this partial-success case so the retry
function returns nil and pagination continues normally
- repoWithIssueCount carries the count matched by databaseId; repos where
Issues:Read is missing get count 0 without any error or dropped data
- isFatalError() + early break added so true auth failures (bad credentials,
401/403) stop pagination immediately instead of exhausting retries
Minimum required FGPAT permissions for analyze_org: resource owner set to the
target org + Repository > Contents: Read. Members:Read and Issues:Read are not
required.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
445ac10 to
ca62d12
Compare
SUSTAPLE117
approved these changes
Apr 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
analyze_orgfails entirely when using a fine-grained PAT (FGPAT) that doesn't haveIssues: Readpermission:Root cause:
issues { totalCount }is typedIssueConnection!(non-null) in GitHub's GraphQL schema. When a FGPAT lacksIssues: Readon a private repo, GitHub cannot resolve that non-null field and nulls out the entire repo node — not just the issues field. This silently drops private repos from the batch and surfaces as a full batch failure after 3 retries.Fix
Moves issues fetching into a dedicated
issueNodes: repositories(...)GraphQL alias within the same query. The mainrepositoriesselection no longer includesissues, so all repos are always returned regardless ofIssues: Readpermission.The
shurcooL/graphqllibrary unmarshals response data before returning errors. So whenissueNodesgets a FORBIDDEN response,Repositories.Nodesis already fully populated — we detect this partial-success case viaisIssuesPermissionError()and continue normally. Repos whereIssues: Readis missing getopenIssuesCount = 0silently viarepoWithIssueCount.Also adds
isFatalError()so true auth failures (bad credentials, 401/403) stop pagination immediately instead of burning through retries.Minimum required FGPAT permissions
Test plan
analyze_org <org>with a FGPAT scoped to the org with onlyContents: Read— all repos (including private) should be listed and scanned, withopenIssuesCount: 0analyze_org <org>with a FGPAT that also hasIssues: Read—openIssuesCountshould be populated correctly for all reposanalyze_org <org>with an invalid/expired token — should log a single fatal error and stop immediately, not retry 3 times