Skip to content

Commit f54b4df

Browse files
cyberjunkyclaude
andcommitted
fix: detect HTTP 403 Cloudflare challenge before JSON parse in login
A 403 from the SSO/mobile host is a Cloudflare bot challenge returning a non-JSON HTML page, so r.json() threw before the CAPTCHA_REQUIRED check could run — surfacing as a confusing "login failed (non-JSON): HTTP 403". Detect 403 explicitly (same class as 429/CAPTCHA) and raise a clear bot-challenge error that falls through to the next strategy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 7fee7ee commit f54b4df

1 file changed

Lines changed: 12 additions & 0 deletions

File tree

garminconnect/client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,12 @@ def _do_mobile_login(self, sess: Any, email: str, password: str) -> None:
398398
"Mobile login returned 429 — IP rate limited by Garmin"
399399
)
400400

401+
if r.status_code == 403:
402+
raise GarminConnectConnectionError(
403+
"Mobile login: HTTP 403 (Cloudflare bot challenge) — "
404+
"falling through to next strategy"
405+
)
406+
401407
try:
402408
res = r.json()
403409
except Exception as err:
@@ -731,6 +737,12 @@ def _do_portal_web_login(self, sess: Any, email: str, password: str) -> None:
731737
"Portal login POST returned 429 — Cloudflare blocking this request."
732738
)
733739

740+
if r.status_code == 403:
741+
raise GarminConnectConnectionError(
742+
"Portal login: HTTP 403 (Cloudflare bot challenge) — "
743+
"falling through to next strategy"
744+
)
745+
734746
try:
735747
res = r.json()
736748
except Exception as err:

0 commit comments

Comments
 (0)