Repository navigation
Conversation
make_request_with_retry resent the Request it was given, so a retry kept the Authorization header from the first attempt. With --app-id the rate limit window and the installation token both start at the beginning of the run, so when the limit is used up within that hour, the wait for x-ratelimit-reset ends right after the token expires and the retry fails with 401, which stops the backup. make_request_with_retry now takes an optional rebuild_request callable and uses it to build each retry. retrieve_data and retrieve_graphql_data pass one that resolves the token through get_auth again, which creates a new installation token when the cached one is about to expire. retrieve_graphql_data also resolved the token once per call, so its own retry on a RATE_LIMITED error had the same problem. It now resolves the token again for each attempt after the first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JefeUYfnfUPitmyF6hAYjm
Contributor
|
Looks good to merge. Thanks for the fix and contribution @gaupon. |
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.
Follows up on #545.
With
--app-id, a backup that uses up the rate limit stops with 401 after the rate-limit wait.retrieve_dataresolves the token throughget_authon every attempt, so pagination picks up a refreshed installation token. But the retries insidemake_request_with_retry(rate-limit 403/429, 5xx, connection errors) resend theRequestthey were given, with theAuthorizationheader from the first attempt. The installation token and the rate-limit window both start at the beginning of the run. When the limit is used up within that hour, the wait forx-ratelimit-resetends right after the token expires. The retry gets 401, which is not retried, and the backup stops.From a weekly full backup of an organization (
--app-id, issues, pulls and their comments, timelines):HTTP 403 (rate limit exceeded), retrying in 924.0sAPI Error: 401 Unauthorized, run stopsretrieve_graphql_datahas the same problem, and resolves the token only once per call, so its own retry on aRATE_LIMITEDerror in the response body reuses it as well.Changes
make_request_with_retrytakes an optionalrebuild_requestcallable and calls it to build each retry. Callers that do not pass one behave as before.retrieve_dataandretrieve_graphql_datapass one that resolves the token throughget_auth/get_graphql_authagain. When the cached installation token is about to expire, that creates a new one.retrieve_graphql_dataresolves the token again for each attempt after the first, which covers theRATE_LIMITEDretry.tests/test_app_auth.pycover a token that is replaced during the wait for a REST rate-limit 403, a GraphQL rate-limit 403 and a GraphQLRATE_LIMITEDerror. All three fail without this change.Testing
pytest: 213 passed.flake8 --ignore=E501,E203,W503is clean.Live, with
--app-idagainst a private organization. A small wrapper aroundurlopenanswered the first matching request with a rate-limit 403 (reset in 1 second, so the minimum 10 second wait). Before answering, it revoked the token that request carried (DELETE /installation/token, 204) and marked the cached token as expired, standing in for the hour passing. All other requests went to GitHub unchanged.--incremental-by-fileswith--issue-timeline, wait on the cross-reference check)Unable to check ... for new cross-referenceswarningThe
RATE_LIMITEDpath was not tested live, as I couldn't trigger it on demand.Notes
request_as_app(the app JWT, valid for 9 minutes) is unchanged. It is only used to look up the installation and create tokens, so a long wait there is unlikely, and retrying with a new JWT would need a different change._construct_requestlogsRequesting ...each time it is called, so a REST retry now logs that line again.🤖 Generated with Claude Code
https://claude.ai/code/session_01JefeUYfnfUPitmyF6hAYjm