Skip to content

graphql_rate_limit type error has been updated to RATE_LIMIT, not RATE_LIMITED #271

@jarenere

Description

@jarenere

Hi,

On graphql api, when there is a error due to rate limit, the api return

{"errors":[{"type":"RATE_LIMIT","code":"graphql_rate_limit","message":"API rate limit already exceeded for user ID xxxxx."}]}

And on graphql client, try to find the string the error.type = "RATE_LIMITED"

    def parse_graphql_response(
        self, response: "Response[GraphQLResponse]"
    ) -> dict[str, Any]:
        response_data = response.parsed_data
        if response_data.errors:
            # check rate limit exceeded
            # https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api#exceeding-the-rate-limit
            # x-ratelimit-remaining may not be 0, ignore it
            # https://github.com/octokit/plugin-throttling.js/pull/636
            if any(error.type == "RATE_LIMIT" for error in response_data.errors):
                raise PrimaryRateLimitExceeded(
                    response, self._github._extract_retry_after(response)
                )
            raise GraphQLFailed(response_data)
        return cast(dict[str, Any], response_data.data)

i am not sure if there have been more changes on rate limit, in theory retry-after header can be present
https://docs.github.com/en/graphql/overview/rate-limits-and-query-limits-for-the-graphql-api
But I've tried to find information about the different errors that GraphQL can return, and I haven't been able to find them.

Request/response migration query

Request Headers: {'host': 'api.github.com', 'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive', 'user-agent': 'GitHubKit/Python', 'accept': 'application/vnd.github+json', 'content-length': '429', 'content-type': 'application/json', 'authorization': 'token xxxx'}
Request Body: b'{"query":"\\nquery($id: ID!) { \\n    node(id: $id) {\\n        ... on Migration {\\n            id,\\n            sourceUrl,\\n            migrationLogUrl,\\n            migrationSource {\\n                name\\n            },\\n            state,\\n            warningsCount,\\n            failureReason,\\n            repositoryName\\n        }\\n    } \\n}\\n","variables":{"id":"yyyy"}}'
Response Headers: {'date': 'Thu, 08 Jan 2026 16:49:49 GMT', 'content-type': 'application/json; charset=utf-8', 'x-oauth-scopes': 'admin:org, repo, workflow', 'x-accepted-oauth-scopes': 'repo', 'x-github-media-type': 'github.v4; format=json', 'x-ratelimit-limit': '5000', 'x-ratelimit-remaining': '0', 'x-ratelimit-reset': '1767892233', 'x-ratelimit-used': '5018', 'x-ratelimit-resource': 'graphql', 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset', 'access-control-allow-origin': '*', 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload', 'x-frame-options': 'deny', 'x-content-type-options': 'nosniff', 'x-xss-protection': '0', 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin', 'content-security-policy': "default-src 'none'", 'vary': 'Accept-Encoding, Accept, X-Requested-With', 'content-encoding': 'gzip', 'transfer-encoding': 'chunked', 'server': 'github.com', 'x-github-request-id': '4C25:1F1B3F:2B04832:26C1653:695FE02C'}
Response Body: {"errors":[{"type":"RATE_LIMIT","code":"graphql_rate_limit","message":"API rate limit already exceeded for user ID zzzzz."}]}

Request/response list repo query

Request Headers: {'host': 'api.github.com', 'accept-encoding': 'gzip, deflate', 'connection': 'keep-alive', 'user-agent': 'GitHubKit/Python', 'accept': 'application/vnd.github+json', 'content-length': '163', 'content-type': 'application/json', 'authorization': 'token xxxx'}
Request Body: b'{"query":"\\nquery ($owner: String!, $repo: String!) {\\n  repository(owner: $owner, name: $repo) {\\n    name\\n  }\\n}\\n","variables":{"owner":"owner","repo":"repo"}}'
Response Headers: {'date': 'Thu, 08 Jan 2026 17:21:18 GMT', 'content-type': 'application/json; charset=utf-8', 'x-oauth-scopes': 'admin:org, repo, workflow', 'x-accepted-oauth-scopes': 'repo', 'x-github-media-type': 'github.v4; format=json', 'x-ratelimit-limit': '5000', 'x-ratelimit-remaining': '0', 'x-ratelimit-reset': '1767896168', 'x-ratelimit-used': '5002', 'x-ratelimit-resource': 'graphql', 'access-control-expose-headers': 'ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset', 'access-control-allow-origin': '*', 'strict-transport-security': 'max-age=31536000; includeSubdomains; preload', 'x-frame-options': 'deny', 'x-content-type-options': 'nosniff', 'x-xss-protection': '0', 'referrer-policy': 'origin-when-cross-origin, strict-origin-when-cross-origin', 'content-security-policy': "default-src 'none'", 'vary': 'Accept-Encoding, Accept, X-Requested-With', 'content-encoding': 'gzip', 'transfer-encoding': 'chunked', 'server': 'github.com', 'x-github-request-id': '6042:18034E:2DBF8B5:29287C7:695FE78E'}
Response Body: {"errors":[{"type":"RATE_LIMIT","code":"graphql_rate_limit","message":"API rate limit already exceeded for user ID xxxx."}]}

After change error.type to "RATE_LIMIT", It returns the expected exception because it cannot find the headers.

     55 if response_data.errors:
     56     # check rate limit exceeded
     57     # https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api#exceeding-the-rate-limit
     58     # x-ratelimit-remaining may not be 0, ignore it
     59     # https://github.com/octokit/plugin-throttling.js/pull/636
     60     if any(error.type == "RATE_LIMIT" for error in response_data.errors):
---> 61         raise PrimaryRateLimitExceeded(
     62             response, self._github._extract_retry_after(response)
     63         )
     64     raise GraphQLFailed(response_data)
     65 return cast(dict[str, Any], response_data.data)

PrimaryRateLimitExceeded: (Response(200 OK, data_model=<class 'githubkit.graphql.models.GraphQLResponse'>), datetime.timedelta(seconds=3289, microseconds=326017))

Metadata

Metadata

Assignees

No one assigned

    Labels

    GraphQLbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions