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

  1. Inspect response.content / exc to see what body was actually returned (HTML? empty? error text?)
  2. Refresh eToro credentials/session if an HTML auth page is returned
  3. Check for proxy/WAF interception and bypass or authenticate it
  4. 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

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.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/02c59caef3c67604. Report an issue: GitHub.