Skip to content

[GitHubContributors] Badges render "invalid" for large repositories ("history or contributor list is too large") #12186

Open

Description

@Shanwis

Are you experiencing an issue with...

shields.io

🐞 Description

When requesting a GitHub contributors badge for repositories with very large commit histories (such as NixOS/nixpkgs), the badge fails to render a contributor count. In the case of NixOS/nixpkgs:

Image

The badge URL, parameters, and repository are all valid.

Reproducing Upstream API Behavior

  1. Direct Authenticated GitHub CLI Call:
    Running an authenticated request against the contributors endpoint:

    gh api repos/NixOS/nixpkgs/contributors

    returns HTTP 403 Forbidden with the following payload:

    {
      "message": "The history or contributor list is too large to list contributors for this repository via the API.",
      "documentation_url": "https://docs.github.com/rest/repos/repos#list-repository-contributors",
      "status": "403"
    }
  2. Pagination Does Not Bypass the Error:
    Attempting pagination or modifying page sizes (per_page=100, page=1) fails with the identical HTTP 403 response because GitHub's backend aborts the calculation before generating the first page.

  3. Not a Rate Limit Failure:
    The request is authenticated and has ample rate limit quota remaining (x-ratelimit-remaining > 0). This error represents an intentional server-side computation safeguard for massive repositories on GitHub's REST API.

  4. Control Experiment:
    Smaller repositories in the same organization work normally:

    gh api repos/NixOS/nixos/contributors --paginate --slurp | jq 'add | length'
    # Successfully returns contributor count

Current Shields Implementation

  1. Request Execution (services/github/github-contributors.service.js):
    The service requests page 1 with per_page: '1' to extract the total count from the link header:

    const { res, buffer } = await this._request({
      url: `/repos/${user}/${repo}/contributors`,
      options: { searchParams: { page: '1', per_page: '1', anon: isAnon } },
      httpErrors: httpErrorsFor('repo not found'),
    })
  2. Error Translation (services/github/github-helpers.js):
    httpErrorsFor only translates HTTP 404 and 422:

    function httpErrorsFor(notFoundMessage = 'repo not found') {
      return {
        404: notFoundMessage,
        422: notFoundMessage,
      }
    }

    Status 403 is unmapped.

  3. Error Pipeline (core/base-service/check-error-response.js):
    When GitHub returns 403:

    • checkErrorResponse checks res.statusCode !== 200 and res.statusCode < 500.
    • Because httpErrors[403] is undefined, it instantiates an InvalidResponse exception with the fallback defaultPrettyMessage = 'invalid'.
    • BaseService._handleError() in core/base-service/base.js maps this to { isError: true, message: 'invalid', color: 'lightgray' }.

🔗 Link to the badge

💡 Possible Solution

Displaying invalid is misleading to users because it suggests a malformed badge parameter or nonexistent repository rather than an upstream API size limit.

  1. Could GithubContributors (or checkErrorResponse) inspect the response body for "The history or contributor list is too large" and render a more descriptive error badge (such as contributors | too large or contributors | not supported)?
  2. Alternatively, is there any known fallback or alternative approach for obtaining contributor counts on large repositories where GitHub's REST endpoint is unavailable?

Activity

  1. Shanwis commented on Sep 28, 2026

    @Shanwis
    ContributorAuthor

    I would love to work on this, and would appreciate any suggestions on how it should be worked on 🤗

  2. PyvesB commented on Sep 28, 2026

    @PyvesB
    Member

    @DCjanus would you like to pair
    with @Shanwis on this task? :)

  3. DCjanus commented on Sep 28, 2026

    @DCjanus
    Contributor

    Hi @Shanwis — I’d be happy to work with you on this.

    How would you prefer to collaborate? If you’d like to use this as an opportunity to explore the Shields codebase and implement the fix, I can help work through the approach and review your PR. If you’d prefer me to handle the implementation, I’m happy to do that too.

    Either way, I’ll start looking into the problem myself — it’s an interesting one!

  4. Shanwis commented on Sep 28, 2026

    @Shanwis
    ContributorAuthor

    @DCjanus I would prefer to take this opportunity to explore the codebase and try out a fix. I am a new contributor here so would be depending on you guidance 😄.

    I will most probably make a PR relating to this in a day or so.

    Currently thinking of doing the first possible solution by adding a mapping for 403 like we have for 404 and 422.

  5. Shanwis commented on Oct 3, 2026

    @Shanwis
    ContributorAuthor

    Hi, sorry about the delay, things got a bit busy on my side. I will be trying to make the PR as soon as possible

  6. IonBazan commented on Oct 18, 2026

    @IonBazan

    Perhaps GraphQL API could be used instead

    query {
      repository(owner: "NixOS", name: "nixpkgs") {
        mentionableUsers {
          totalCount
        }
      }
    }
  7. Shanwis commented on Oct 23, 2026

    @Shanwis
    ContributorAuthor

    7. Perhaps GraphQL API could be used instead
    query {
    repository(owner: "NixOS", name: "nixpkgs") {
    mentionableUsers {
    totalCount
    }
    }
    }

    That could work, thanks!
    But mentionableUsers is not the same as Contibutors 😅, per the schema it's "users that can be mentioned in the
    context of the repository" (issue/PR participants, collaborators), not commit authors. I could not find a contributor query in it as well.

  8. Shanwis commented on Oct 24, 2026

    @Shanwis
    ContributorAuthor

    I have raised a PR making it so that the 403 error with body "The history or contributor list is too large to list contributors for this repository via the API" throws InvalidResponse with message High contributor count.
    @DCjanus @PyvesB Do check out the PR when you get the time 🤗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    service-badgeNew or updated service badge

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions