René's URL Explorer Experiment


Title: Retry transient full-scan upload failures (502/503/504/408, dropped connections) by mtorp · Pull Request #232 · SocketDev/socket-python-cli · GitHub

Open Graph Title: Retry transient full-scan upload failures (502/503/504/408, dropped connections) by mtorp · Pull Request #232 · SocketDev/socket-python-cli

X Title: Retry transient full-scan upload failures (502/503/504/408, dropped connections) by mtorp · Pull Request #232 · SocketDev/socket-python-cli

Description: Problem The full-scan upload (POST /v0/orgs//full-scans) makes exactly one attempt. When it fails, the entire run dies — for --reach runs that means a completed multi-hour tier-1 reachability analysis produces no scan and no report. Uploads can fail transiently at the gateway/connection level — an HTTP 502/503/504/408, a dropped or reset connection, or a client-side timeout — without the server having created the scan. A retried upload almost always succeeds. Change Core.create_full_scan now retries the fullscans.post call: Up to 3 total attempts, waiting ~10s before attempt 2 and ~30s before attempt 3 (plus up to 2s jitter so CI fleets don't retry in lock-step), with a log.warning before each retry. Retries transient failures only, as classified by the SDK: requires socketdev>=3.3.0 (SocketDev/socket-sdk-python#93), where do_request records the HTTP status code on every exception it raises and APIFailure.is_transient_error() owns the classification — true for HTTP 408/502/503/504, dropped/reset connections, and client-side timeouts. The CLI encodes no knowledge of the SDK exception hierarchy and parses no message text, so SDK restructuring can't silently break the classification. Never retried: deterministic errors (400/401/403/404/429), responses that came back with an error payload, and unexpected errors wrapped in a bare APIFailure. Note: uv.lock is regenerated once socketdev 3.3.0 is released to PyPI (blocked on SocketDev/socket-sdk-python#93); CI is expected to fail on dependency resolution until then. Safety No duplicate scans: in these failure modes the server never finished reading the request body, so no scan was created — a retry cannot duplicate one. In the rare case where a gateway timeout races a request the server later completes, the extra scan is benign and superseded by the retry (as if the CLI had run twice). Files are rebuilt per attempt: fullscans.post(use_lazy_loading=True) rebuilds its LazyFileLoaders from the plain paths on every call, so re-invoking it is safe (the loaders from a failed attempt are exhausted/closed and must not be reused). Temp .br facts files survive retries: the retry loop lives inside the existing try/finally, so the brotli-compressed .socket.facts.json.br siblings are only cleaned up after the last attempt. Testing New tests/unit/test_full_scan_retry.py (16 tests): retry on 502 then success, exhausting attempts re-raises, retry on catch-all 408/503/504, retry on connection-level errors, no retry on 400 / dedicated 4xx classes / error payloads, .br temp-file lifecycle across retries (success and exhaustion), and that the retry decision delegates to APIFailure.is_transient_error() (the classification truth table itself is tested in the SDK, next to the code that raises). Full suite against socketdev 3.3.0: 364 passed, 2 pre-existing skips.

Open Graph Description: Problem The full-scan upload (POST /v0/orgs/<org>/full-scans) makes exactly one attempt. When it fails, the entire run dies — for --reach runs that means a completed multi-hour tier-1 reachab...

X Description: Problem The full-scan upload (POST /v0/orgs/&lt;org&gt;/full-scans) makes exactly one attempt. When it fails, the entire run dies — for --reach runs that means a completed multi-hour tier-1...

Opengraph URL: https://github.com/SocketDev/socket-python-cli/pull/232

X: @github

direct link

Domain: github.com

route-pattern/:user_id/:repository/pull/:id/files(.:format)
route-controllerpull_requests
route-actionfiles
fetch-noncev2:5bb3b56e-1512-06f2-8dfc-87c628622b4a
current-catalog-service-hashae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b
request-id9D44:11A2A:3224684:3300048:6A4F0623
html-safe-nonceb5fa3555366df20d1e0f837afac6535f42490396cd7c0e90853f189948297475
visitor-payloadeyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5RDQ0OjExQTJBOjMyMjQ2ODQ6MzMwMDA0ODo2QTRGMDYyMyIsInZpc2l0b3JfaWQiOiI0ODgwMzMxMjQxMjg1ODkzNDciLCJyZWdpb25fZWRnZSI6InNlYSIsInJlZ2lvbl9yZW5kZXIiOiJzZWEifQ==
visitor-hmac61d3e60592917955e51fecba09a37d40d03142381c20162bd0df599aa6edfb68
hovercard-subject-tagpull_request:3837847141
github-keyboard-shortcutsrepository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot
google-site-verificationApib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I
octolytics-urlhttps://collector.github.com/github/collect
analytics-location///pull_requests/show/files
fb:app_id1401488693436528
apple-itunes-appapp-id=1477376905, app-argument=https://github.com/SocketDev/socket-python-cli/pull/232/files
twitter:imagehttps://avatars.githubusercontent.com/u/5579277?s=400&v=4
twitter:cardsummary_large_image
og:imagehttps://avatars.githubusercontent.com/u/5579277?s=400&v=4
og:image:altProblem The full-scan upload (POST /v0/orgs/<org>/full-scans) makes exactly one attempt. When it fails, the entire run dies — for --reach runs that means a completed multi-hour tier-1 reachab...
og:site_nameGitHub
og:typeobject
hostnamegithub.com
expected-hostnamegithub.com
Noneb92d11c0aa4a77d54ef4af1078b6a15fb5a70a215b30c4ecf28889d5a8e656d9
turbo-cache-controlno-preview
diff-viewunified
go-importgithub.com/SocketDev/socket-python-cli git https://github.com/SocketDev/socket-python-cli.git
octolytics-dimension-user_id69326764
octolytics-dimension-user_loginSocketDev
octolytics-dimension-repository_id802230750
octolytics-dimension-repository_nwoSocketDev/socket-python-cli
octolytics-dimension-repository_publictrue
octolytics-dimension-repository_is_forkfalse
octolytics-dimension-repository_network_root_id802230750
octolytics-dimension-repository_network_root_nwoSocketDev/socket-python-cli
turbo-body-classeslogged-out env-production page-responsive full-width
disable-turbotrue
browser-stats-urlhttps://api.github.com/_private/browser/stats
browser-errors-urlhttps://api.github.com/_private/browser/errors
release2b8f23afb982271f1b22258a94aede67a6b77760
ui-targetfull
theme-color#1e2327
color-schemelight dark

Links:

Skip to contenthttps://github.com/SocketDev/socket-python-cli/pull/232/files#start-of-content
https://github.com/
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FSocketDev%2Fsocket-python-cli%2Fpull%2F232%2Ffiles
GitHub CopilotWrite better code with AIhttps://github.com/features/copilot
GitHub Copilot appDirect agents from issue to mergehttps://github.com/features/ai/github-app
MCP RegistryNewIntegrate external toolshttps://github.com/mcp
ActionsAutomate any workflowhttps://github.com/features/actions
CodespacesInstant dev environmentshttps://github.com/features/codespaces
IssuesPlan and track workhttps://github.com/features/issues
Code ReviewManage code changeshttps://github.com/features/code-review
GitHub Advanced SecurityFind and fix vulnerabilitieshttps://github.com/security/advanced-security
Code securitySecure your code as you buildhttps://github.com/security/advanced-security/code-security
Secret protectionStop leaks before they starthttps://github.com/security/advanced-security/secret-protection
Why GitHubhttps://github.com/why-github
Documentationhttps://docs.github.com
Bloghttps://github.blog
Changeloghttps://github.blog/changelog
Marketplacehttps://github.com/marketplace
View all featureshttps://github.com/features
Enterpriseshttps://github.com/enterprise
Small and medium teamshttps://github.com/team
Startupshttps://github.com/enterprise/startups
Nonprofitshttps://github.com/solutions/industry/nonprofits
App Modernizationhttps://github.com/solutions/use-case/app-modernization
DevSecOpshttps://github.com/solutions/use-case/devsecops
DevOpshttps://github.com/solutions/use-case/devops
CI/CDhttps://github.com/solutions/use-case/ci-cd
View all use caseshttps://github.com/solutions/use-case
Healthcarehttps://github.com/solutions/industry/healthcare
Financial serviceshttps://github.com/solutions/industry/financial-services
Manufacturinghttps://github.com/solutions/industry/manufacturing
Governmenthttps://github.com/solutions/industry/government
View all industrieshttps://github.com/solutions/industry
View all solutionshttps://github.com/solutions
AIhttps://github.com/resources/articles?topic=ai
Software Developmenthttps://github.com/resources/articles?topic=software-development
DevOpshttps://github.com/resources/articles?topic=devops
Securityhttps://github.com/resources/articles?topic=security
View all topicshttps://github.com/resources/articles
Customer storieshttps://github.com/customer-stories
Events & webinarshttps://github.com/resources/events
Ebooks & reportshttps://github.com/resources/whitepapers
Business insightshttps://github.com/solutions/executive-insights
GitHub Skillshttps://skills.github.com
Documentationhttps://docs.github.com
Customer supporthttps://support.github.com
Community forumhttps://github.com/orgs/community/discussions
Trust centerhttps://github.com/trust-center
Partnershttps://github.com/partners
View all resourceshttps://github.com/resources
GitHub SponsorsFund open source developershttps://github.com/open-source/sponsors
Security Labhttps://securitylab.github.com
Maintainer Communityhttps://maintainers.github.com
Acceleratorhttps://github.com/open-source/accelerator
GitHub Starshttps://stars.github.com
Archive Programhttps://archiveprogram.github.com
Topicshttps://github.com/topics
Trendinghttps://github.com/trending
Collectionshttps://github.com/collections
Enterprise platformAI-powered developer platformhttps://github.com/enterprise
GitHub Advanced SecurityEnterprise-grade security featureshttps://github.com/security/advanced-security
Copilot for BusinessEnterprise-grade AI featureshttps://github.com/features/copilot/copilot-business
Premium SupportEnterprise-grade 24/7 supporthttps://github.com/enterprise/premium-support
Pricinghttps://github.com/pricing
Search syntax tipshttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
documentationhttps://docs.github.com/search-github/github-code-search/understanding-github-code-search-syntax
Sign in https://github.com/login?return_to=https%3A%2F%2Fgithub.com%2FSocketDev%2Fsocket-python-cli%2Fpull%2F232%2Ffiles
Sign up https://github.com/signup?ref_cta=Sign+up&ref_loc=header+logged+out&ref_page=%2F%3Cuser-name%3E%2F%3Crepo-name%3E%2Fpull_requests%2Fshow%2Ffiles&source=header-repo&source_repo=SocketDev%2Fsocket-python-cli
Reloadhttps://github.com/SocketDev/socket-python-cli/pull/232/files
Reloadhttps://github.com/SocketDev/socket-python-cli/pull/232/files
Reloadhttps://github.com/SocketDev/socket-python-cli/pull/232/files
Please reload this pagehttps://github.com/SocketDev/socket-python-cli/pull/232/files
SocketDev https://github.com/SocketDev
socket-python-clihttps://github.com/SocketDev/socket-python-cli
Notifications https://github.com/login?return_to=%2FSocketDev%2Fsocket-python-cli
Fork 11 https://github.com/login?return_to=%2FSocketDev%2Fsocket-python-cli
Star 9 https://github.com/login?return_to=%2FSocketDev%2Fsocket-python-cli
Code https://github.com/SocketDev/socket-python-cli
Pull requests 5 https://github.com/SocketDev/socket-python-cli/pulls
Actions https://github.com/SocketDev/socket-python-cli/actions
Models https://github.com/SocketDev/socket-python-cli/models
Security and quality 0 https://github.com/SocketDev/socket-python-cli/security
Insights https://github.com/SocketDev/socket-python-cli/pulse
Code https://github.com/SocketDev/socket-python-cli
Pull requests https://github.com/SocketDev/socket-python-cli/pulls
Actions https://github.com/SocketDev/socket-python-cli/actions
Models https://github.com/SocketDev/socket-python-cli/models
Security and quality https://github.com/SocketDev/socket-python-cli/security
Insights https://github.com/SocketDev/socket-python-cli/pulse
Sign up for GitHub https://github.com/signup?return_to=%2FSocketDev%2Fsocket-python-cli%2Fissues%2Fnew%2Fchoose
terms of servicehttps://docs.github.com/terms
privacy statementhttps://docs.github.com/privacy
Sign inhttps://github.com/login?return_to=%2FSocketDev%2Fsocket-python-cli%2Fissues%2Fnew%2Fchoose
Martin Torp (mtorp)https://github.com/mtorp
mainhttps://github.com/SocketDev/socket-python-cli/tree/main
retry-transient-full-scan-upload-failureshttps://github.com/SocketDev/socket-python-cli/tree/retry-transient-full-scan-upload-failures
Conversation 10 https://github.com/SocketDev/socket-python-cli/pull/232
Commits 4 https://github.com/SocketDev/socket-python-cli/pull/232/commits
Checks 26 https://github.com/SocketDev/socket-python-cli/pull/232/checks
Files changed https://github.com/SocketDev/socket-python-cli/pull/232/files
Please reload this pagehttps://github.com/SocketDev/socket-python-cli/pull/232/files
Retry transient full-scan upload failures (502/503/504/408, dropped connections) https://github.com/SocketDev/socket-python-cli/pull/232/files#top
Show all changes 4 commits https://github.com/SocketDev/socket-python-cli/pull/232/files
d32806b Retry transient full-scan upload failures (502/503/504/408, dropped c… mtorp Jun 10, 2026 https://github.com/SocketDev/socket-python-cli/pull/232/commits/d32806b54082b0c5f6c222e9aae360a1a37c08f3
8dc0970 docs: drop the 'retry almost always succeeds' claim from retry comments mtorp Jun 10, 2026 https://github.com/SocketDev/socket-python-cli/pull/232/commits/8dc097002b5126a85d608fa24492be17101773e8
487557a Move transient-error classification into the SDK; simplify retry loop mtorp Jun 10, 2026 https://github.com/SocketDev/socket-python-cli/pull/232/commits/487557abc917b147489942d703cb36b121ce7f60
6bc8fe8 Lock socketdev 3.3.0 mtorp Jun 10, 2026 https://github.com/SocketDev/socket-python-cli/pull/232/commits/6bc8fe831e19651d1c9c120b0abf9ab442b9fecd
Clear filters https://github.com/SocketDev/socket-python-cli/pull/232/files
Please reload this pagehttps://github.com/SocketDev/socket-python-cli/pull/232/files
Please reload this pagehttps://github.com/SocketDev/socket-python-cli/pull/232/files
CHANGELOG.md https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed
pyproject.toml https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711
__init__.py https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-9ae7a3b3f6a847c0c7bbe145ba187b0f9a0cfd2e1316ab84d135c13830934814
__init__.py https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-f0756415918d69dd618562021c7ee058e5161d1d3c1c49afbd89b3b911883a4b
test_full_scan_retry.py https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-12424c6ffc8eec64d3cd22523ab524a453a54405cbc6ee1063820b19c6b862e2
uv.lock https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-84321598744d84dbee2318e634c74c9aae39a1c253f1c4bd17ebf9ef2f807b11
https://github.com/SocketDev/socket-python-cli/blob/main/.github/CODEOWNERS#L1
CHANGELOG.mdhttps://github.com/SocketDev/socket-python-cli/pull/232/files#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed
View file https://github.com/SocketDev/socket-python-cli/blob/6bc8fe831e19651d1c9c120b0abf9ab442b9fecd/CHANGELOG.md
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/SocketDev/socket-python-cli/pull/232/{{ revealButtonHref }}
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed
https://github.com/SocketDev/socket-python-cli/blob/main/.github/CODEOWNERS#L1
pyproject.tomlhttps://github.com/SocketDev/socket-python-cli/pull/232/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711
View file https://github.com/SocketDev/socket-python-cli/blob/6bc8fe831e19651d1c9c120b0abf9ab442b9fecd/pyproject.toml
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/SocketDev/socket-python-cli/pull/232/{{ revealButtonHref }}
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711
https://github.com/SocketDev/socket-python-cli/blob/main/.github/CODEOWNERS#L1
socketsecurity/__init__.pyhttps://github.com/SocketDev/socket-python-cli/pull/232/files#diff-9ae7a3b3f6a847c0c7bbe145ba187b0f9a0cfd2e1316ab84d135c13830934814
View file https://github.com/SocketDev/socket-python-cli/blob/6bc8fe831e19651d1c9c120b0abf9ab442b9fecd/socketsecurity/__init__.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/SocketDev/socket-python-cli/pull/232/{{ revealButtonHref }}
https://github.com/SocketDev/socket-python-cli/blob/main/.github/CODEOWNERS#L1
socketsecurity/core/__init__.pyhttps://github.com/SocketDev/socket-python-cli/pull/232/files#diff-f0756415918d69dd618562021c7ee058e5161d1d3c1c49afbd89b3b911883a4b
View file https://github.com/SocketDev/socket-python-cli/blob/6bc8fe831e19651d1c9c120b0abf9ab442b9fecd/socketsecurity/core/__init__.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/SocketDev/socket-python-cli/pull/232/{{ revealButtonHref }}
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-f0756415918d69dd618562021c7ee058e5161d1d3c1c49afbd89b3b911883a4b
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-f0756415918d69dd618562021c7ee058e5161d1d3c1c49afbd89b3b911883a4b
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-f0756415918d69dd618562021c7ee058e5161d1d3c1c49afbd89b3b911883a4b
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-f0756415918d69dd618562021c7ee058e5161d1d3c1c49afbd89b3b911883a4b
https://github.com/SocketDev/socket-python-cli/pull/232/files#diff-f0756415918d69dd618562021c7ee058e5161d1d3c1c49afbd89b3b911883a4b
https://github.com/SocketDev/socket-python-cli/blob/main/.github/CODEOWNERS#L1
tests/unit/test_full_scan_retry.pyhttps://github.com/SocketDev/socket-python-cli/pull/232/files#diff-12424c6ffc8eec64d3cd22523ab524a453a54405cbc6ee1063820b19c6b862e2
View file https://github.com/SocketDev/socket-python-cli/blob/6bc8fe831e19651d1c9c120b0abf9ab442b9fecd/tests/unit/test_full_scan_retry.py
Open in desktop https://desktop.github.com
https://github.co/hiddenchars
https://github.com/SocketDev/socket-python-cli/pull/232/{{ revealButtonHref }}
Please reload this pagehttps://github.com/SocketDev/socket-python-cli/pull/232/files
Please reload this pagehttps://github.com/SocketDev/socket-python-cli/pull/232/files
https://github.com
Termshttps://docs.github.com/site-policy/github-terms/github-terms-of-service
Privacyhttps://docs.github.com/site-policy/privacy-policies/github-privacy-statement
Securityhttps://github.com/security
Statushttps://www.githubstatus.com/
Communityhttps://github.community/
Docshttps://docs.github.com/
Contacthttps://support.github.com?tags=dotcom-footer

Viewport: width=device-width


URLs of crawlers that visited me.