Bug with GitHub GraphQL API (pagination over DependencyManifests)

I’ve been trying to work with GitHub GraphQL recently and so far every time I needed pagination the API responded as expected until I tried paginating over DepenencyManifests of a repository. It seems like the first argument isn’t interpreted correctly.

Firstly I’ll explain the sample bug case in theory, and then I’ll attach corresponding queries and responses to help reproducing the bug case.
Let’s say we want to paginate over dependency manifests of the angular/angular repo (which has around ~100 dependency manifests if not more).

  1. I ask the API for the first 4 manifests → API responds with the first 4 manifests (all good)
  2. I ask the API for the first 2 manifests → API responds with the first 2 manifests (still all good so far)
  3. I ask the API for the first 2 manifests after the 2nd manifest → API responds with an empty array (bug?)
  4. I ask the API for the first 4 manifests after the 2nd manifest → API responds with only 2 manifests after the 2nd manifest (bug? - that supposed to happen in the previous query)

Now, to transfer that to real queries and responses:

  1. I ask the API for the first 4 manifests:
repository(owner: "angular", name: "angular") {
    dependencyGraphManifests(first: 4) {
      totalCount
      edges {
          node {
              filename
          }
          cursor
      }
      pageInfo {
        endCursor
        hasNextPage
      }
    }
  }

API responds with the first 4 manifests:

{
    "data":{"repository":{"dependencyGraphManifests":{"totalCount":4,"edges":[
            {"node":{"filename":"package.json"},"cursor":"MQ"},
            {"node":{"filename":"yarn.lock"},"cursor":"Mg"},
            {"node":{"filename":"aio/package.json"},"cursor":"Mw"},
            {"node":{"filename":"aio/yarn.lock"},"cursor":"NA"}],
        "pageInfo":{"endCursor":"NA","hasNextPage":false}}}}
}
  1. I ask the API for the first 2 manifests:
repository(owner: "angular", name: "angular") {
  dependencyGraphManifests(first: 2) {
    totalCount
    edges {
        node {
            filename
        }
        cursor
    }
    pageInfo {
      endCursor
      hasNextPage
    }
  }
}

API responds with the first 2 manifests:

{
    "data":{"repository":{"dependencyGraphManifests":{"totalCount":2,"edges":[
        {"node":{"filename":"package.json"},"cursor":"MQ"},
        {"node":{"filename":"yarn.lock"},"cursor":"Mg"}],
    "pageInfo":{"endCursor":"Mg","hasNextPage":false}}}}
}
  1. I ask the API for the first 2 manifests after the 2nd manifest:
repository(owner: "angular", name: "angular") {
  dependencyGraphManifests(first: 2, after: "Mg") {
    totalCount
    edges {
        node {
            filename
        }
        cursor
    }
    pageInfo {
      endCursor
      hasNextPage
    }
  }
}

API responds with an empty array (notice the totalCount parameter saying “2”):

{
    "data":{"repository":{"dependencyGraphManifests":{"totalCount":2,"edges":[],
        "pageInfo":{"endCursor":null,"hasNextPage":false}}}}
}
  1. I ask the API for the first 4 manifests after the 2nd manifest:
repository(owner: "angular", name: "angular") {
  dependencyGraphManifests(first: 4, after: "Mg") {
    totalCount
    edges {
        node {
            filename
        }
        cursor
    }
    pageInfo {
      endCursor
      hasNextPage
    }
  }
}

API responds with only 2 manifests after the 2nd manifest (notice the totalCount parameter saying “4”):

{
    "data":{"repository":{"dependencyGraphManifests":{"totalCount":4,"edges":[
            {"node":{"filename":"aio/package.json"},"cursor":"Mw"},
            {"node":{"filename":"aio/yarn.lock"},"cursor":"NA"}],
        "pageInfo":{"endCursor":"NA","hasNextPage":false}}}}
}

To me it seems like there’s a bug with interpreting the first argument when fetching manifests. I don’t know whether this is or is not the expected behaviour of the API (I’m guessing not). How can I achieve a traditional GraphQL pagination over DependencyManifests instead?

1 Like

Hi!
I’m experiencing the same issue, but as a temporary workaround you can paginate the results backwards using last and before arguments. The downside of this approach is that the queries timeout more often as they seem to cause more load on GitHub’s API.