Repository navigation
A Mercor 410 is not_found (exit 4); a 429 is throttled: backoff, then exit 3 or 6 - #10
Merged
Merged
Conversation
… exit 3 or 6 410 joins 404 as not_found in the classifier. 429 is a new "throttled" state: retried within the existing block-retry budget with a doubling pause (twice --retry-delay, capped at 60 s), never solved, and if it persists the run stops with stop reason "throttled" (exit 3, or 6 after rows). A 429 without a payload used to end as exit 4 "completed". Selenium and pyppeteer now name a 403 "blocked_refused" like Playwright, and scraper_api_client.py reports a 403 or a persistent 429 through finish_run with the same pause between its attempts. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01CKsd7q25N19WzUZjrAdzx8
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.
Problem
#7 and #8 settled 404 (exit 4) and 5xx (retry, then exit 5 or 6). The other 4xx statuses from Mercor were not handled consistently:
unknown, then ended as exit 4 with stop reasoncompleted: a throttled run claimed an empty result.blocked(exit 3), but the stop reason differed by engine. Playwright saidblocked_refused; Selenium and pyppeteer saidblocked_cloudflare (hard block).scraper_api_client.pyreturned a bare 3 without going throughfinish_run.Resulting behaviour
The same in Playwright, Selenium, pyppeteer and
scraper_api_client.py. The API client reads the target status fromhttp_code.not_foundjobs_not_foundblockedblocked_refusedthrottled(new)--retry-delay, doubling, capped at 60 s; never solvedthrottledA page that carries its records is still
content, whatever the status.In
scraper_api_client.py:--retriesattempts for a 429.finish_run. Earlier output is kept, and with--allow-emptythe sidecar names the stop reason.Evidence
New checks:
check_the_target_4xx_statuses_classify_by_what_they_say: the classifier on real fixtures (NOT_FOUND_HTML, a captured 404 page) and on a small refusal body; a fixture with records stayscontent; the pause schedule and its cap.check_target_4xx_statuses_agree_in_every_engine: each engine's realscrape()and_fetch_one_page, with only the browser primitives stubbed. For 410, 403 and 429 it checks:check_target_4xx_statuses_in_the_scraper_api_client: the realmain()withrequests.poststubbed. It checks the exit code, the number of attempts, the pauses ([2.0, 4.0]for 429 against[1, 1]for 403) and the sidecar.Planted-fault controls (run in the Playwright venv). Each one went red on the named check, and the suite was green again after restore:
completed, which is the old behaviour.throttlednot counted as blocked.throttledstop reason was dropped.The Selenium and pyppeteer runs also caught the
cloudflare (hard block)label before it was unified.Suites:
Engine libraries were installed without browser downloads.
ci_checks.py --allwas OK.No paid calls, no proxies, no credentials and no live requests were made.
Not changed
Retry-Afteris not read. Selenium exposes no response headers, and the pause schedule is the same in every engine.finish_runkeeps its existing--allow-emptybehaviour. A zero-row sidecar saysfailedwhatever the cause; the stop reason says which. A blocked run with--allow-emptycan still write an empty file over earlier output. The sibling repos'--allow-emptypatch would cover it.🤖 Generated with Claude Code
https://claude.ai/code/session_01CKsd7q25N19WzUZjrAdzx8