HKUDS/Vibe-Trading · error · EtoroAPIError
invalid JSON response: {exc}
Error message
invalid JSON response: {exc} What it means
Raised by EtoroClient.request when the HTTP request succeeded (non-empty body) but response.json() failed with ValueError. The eToro API endpoint returned a non-JSON body (HTML error page, empty-ish payload, or truncated response).
Source
Thrown at agent/src/trading/connectors/etoro/client.py:339
continue
raise EtoroAPIError(f"network error: {exc}") from exc
if response.status_code == 429 and allow_retry and attempt + 1 < attempts:
retry_after = response.headers.get("Retry-After")
delay = float(retry_after) if retry_after else backoff[min(attempt, len(backoff) - 1)]
time.sleep(delay)
continue
if response.status_code >= 400:
detail = _response_error_body(response)
raise EtoroAPIError(f"HTTP {response.status_code}: {detail}")
if not response.content:
return {}
try:
return response.json()
except ValueError as exc:
raise EtoroAPIError(f"invalid JSON response: {exc}") from exc
if last_exc is not None:
raise EtoroAPIError(f"network error: {last_exc}")
raise EtoroAPIError("request failed without response")
def _build_default_client(cfg: EtoroConfig) -> EtoroClient:
"""Build the production HTTP client for one eToro configuration."""
return EtoroClient(cfg)
_default_client_factory: Callable[[EtoroConfig], EtoroClient] = _build_default_client
def make_client(cfg: EtoroConfig) -> EtoroClient:
"""Build the REST client for a config (tests may override via ``set_client_factory``)."""
return _default_client_factory(cfg)
View on GitHub (pinned to 80ffdda44c)
Solutions
- Inspect response.content / exc to see what body was actually returned (HTML? empty? error text?)
- Refresh eToro credentials/session if an HTML auth page is returned
- Check for proxy/WAF interception and bypass or authenticate it
- Verify the base URL and endpoint path are current
Example fix
// before
return response.json()
// after
try:
return response.json()
except ValueError as exc:
raise EtoroAPIError(f"invalid JSON response: {exc}") from exc Defensive patterns
Strategy: try-catch
Try / catch
try:
data = client.request('GET', path)
except EtoroAPIError as exc:
if 'invalid JSON response' in str(exc):
logger.error('non-JSON body from eToro: %s', exc)
raise Prevention
- Log response content type and body snippet when JSON parsing fails
- Keep eToro session/credentials fresh so auth pages are not returned
- Route through a trusted network path without HTML-injecting proxies
When it happens
Trigger: Any eToro API call (quotes, instruments, orders) where the server or an intermediary (proxy, CDN, WAF) returns HTML/plain-text instead of JSON — e.g. 200 with an HTML login page, rate-limit page, or gateway error.
Common situations: Session/auth cookies expired so the endpoint serves an HTML login page; Cloudflare/WAF challenge; wrong base URL; proxy injecting an error page; API version change returning text.
Understand the failure class
Background: "Invalid JSON response" and "Failed to parse response" errors: when an API answers 200 but the body isn't the JSON your library expected — this error's family across 28 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- request failed without response
- Trading 212 API returned invalid JSON.
- Feishu QR login requires a JSON agent config; use ~/.vibe-tr
- agent config 'channels' must be an object
- agent config 'channels.feishu' must be an object
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/02c59caef3c67604.
Report an issue: GitHub.