Repository navigation
fix(mtg): don't ask again inside the 30 seconds a 429 limits access for - #87
Merged
Merged
Conversation
…#81) Scryfall limits access for 30 seconds after a 429. Without a usable Retry-After the client retried after 1 and then 2 seconds, so all three attempts landed inside that window. It now ends the call at once with a RateLimitedError that carries no wait, whichever attempt the 429 answers; the job's retry, 30 seconds later at the soonest, is the next request. A 5xx without the header keeps its 1 and 2 seconds, and a usable Retry-After is honoured as before. Negative, non-numeric, empty and past values count as none. Chosen over waiting 30 seconds in the call: a retry at the 30th second is the earliest one that could work and the likeliest to be turned away, and a second 429 there is the overload the page warns about. Raising keeps the wait in the queue, as #74 did for a long Retry-After. The art build therefore stops at one such 429 from the image host, which its specs now pin. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
End to end through the job: one request to Scryfall, the run closed as failed with the reason, and the job queued to run again 30 seconds later. Seen failing against the client before its fix (3 requests, the old message). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The grace and beat comments gave one figure for an image's waits. They now say which case it is: 60 seconds when each Retry-After asks for 30, 3 seconds after server errors without one, and none after a 429 without one, which stops the build. The rate-limit error's comment said the source "kept answering"; one answer is now enough. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
FR-3, FR-4 and the error scenarios, version 1.3.0. Also records what Scryfall's documentation says of a 429 (30 seconds of limited access) and what it doesn't (whether one carries Retry-After). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
AC-3.4, AC-3.6, Reliability and the error scenarios, version 1.3.0. A 5xx without the header keeps its 1 and 2 seconds. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…#81) The floor was 30 seconds, exactly the time Scryfall says a 429 limits access for. The wait runs from when the error is handled, so the next request cleared that window only by the dispatcher's polling delay. 45 is the documented 30 plus a margin. The client's own cap stays at 30. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Obeyed, a zero put all three requests about 0.2 seconds apart inside the 30 seconds a 429 limits access for. A 429 that asks for zero (or an HTTP date that is now) ends the call at once, like one that names no wait. A 5xx that asks for zero is still retried at once. A whitespace-only header was already no wait; it is now pinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ued to retry (#81) End to end: the client's error, the job's retry through Solid Queue and the page, with the retry's time 45 seconds on. Seen failing on the time against the 30-second floor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ps the build (#81) Specs 002 and 011, still 1.3.0 (unreleased): the job's shortest wait is 45 seconds, a Retry-After of zero on a 429 counts as none, and spec 011's 5xx row says a 5xx asking for more than 30 seconds stops the build. The 1.2.0 history rows keep the 30 seconds they recorded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…floor is 45 seconds (#81) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Base automatically changed from
079-art-index-stalled-and-retry-reason
to
main
October 14, 2026 02:14
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.
After a 429 with no usable
Retry-After, the Scryfall client no longer asks again inside the 30 seconds Scryfall says a 429 limits access for. The call ends at once and the job comes back 45 seconds later.Closes #81
Stacked on #85 (the fix for #79 and #80): both edit spec 011's version history and the same
CLAUDE.mdparagraph, so this branch merges that one. Merge #85 first.What changed
Retry-Afterends the call at once withCatalog::Sources::RateLimitedErrorcarrying no wait, on any attempt, forget_jsonandfetch_image. Before, the client retried after 1 and 2 seconds, so all three attempts landed inside the window. "No usable" covers an absent, empty, whitespace-only, negative, non-numeric or past-dated header, and now a zero: obeyingRetry-After: 0allowed three requests in about 0.2 seconds.Catalog::RateLimitRetry::SHORTEST_WAIT, was 30). The retry is scheduled from when the error is handled, so at 30 the next request cleared the window only by the dispatcher's polling delay.Retry-Afterof 1 to 30 seconds is slept exactly; a longer one ends the call carrying the wait; the worst-case sleep per call stays 60 seconds, so the art build's 2-minute rule holds.CLAUDE.mdand the comments inclient.rb,art_build.rbandart/build.rbstate the new figures.What Scryfall's pages say
Their rate-limits, API overview and errors pages state that a 429 limits access for 30 seconds, that continuing may lead to a ban, and that
*.scryfall.iohas no rate limits. None mentionsRetry-After. What a real 429 carries is still unobserved (no rate limit was provoked to find out), so both cases are specified.Decisions for you
Verification
bin/ci: passed, 1405 examples, 0 failures, 1 pending (the art agreement spec, unrelated).CLAUDE.mdsentence, one admin-page example, one spec 011 row) are the last five commits.Known limits and follow-ups
Retry-Afterof 1 to 29 seconds is still obeyed, although the documented limit is 30. It is Scryfall's own number.docs/roadmap.mdstill lists Scryfall client retries inside the 30 seconds a 429 limits access for #81 as open.🤖 Generated with Claude Code