{"record":{"id":"02c59caef3c67604","repo":"HKUDS/Vibe-Trading","slug":"invalid-json-response-exc","errorCode":null,"errorMessage":"invalid JSON response: {exc}","messagePattern":"invalid JSON response: (.+?)","errorType":"exception","errorClass":"EtoroAPIError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/etoro/client.py","lineNumber":339,"sourceCode":"                    continue\n                raise EtoroAPIError(f\"network error: {exc}\") from exc\n\n            if response.status_code == 429 and allow_retry and attempt + 1 < attempts:\n                retry_after = response.headers.get(\"Retry-After\")\n                delay = float(retry_after) if retry_after else backoff[min(attempt, len(backoff) - 1)]\n                time.sleep(delay)\n                continue\n\n            if response.status_code >= 400:\n                detail = _response_error_body(response)\n                raise EtoroAPIError(f\"HTTP {response.status_code}: {detail}\")\n\n            if not response.content:\n                return {}\n            try:\n                return response.json()\n            except ValueError as exc:\n                raise EtoroAPIError(f\"invalid JSON response: {exc}\") from exc\n\n        if last_exc is not None:\n            raise EtoroAPIError(f\"network error: {last_exc}\")\n        raise EtoroAPIError(\"request failed without response\")\n\n\ndef _build_default_client(cfg: EtoroConfig) -> EtoroClient:\n    \"\"\"Build the production HTTP client for one eToro configuration.\"\"\"\n    return EtoroClient(cfg)\n\n\n_default_client_factory: Callable[[EtoroConfig], EtoroClient] = _build_default_client\n\n\ndef make_client(cfg: EtoroConfig) -> EtoroClient:\n    \"\"\"Build the REST client for a config (tests may override via ``set_client_factory``).\"\"\"\n    return _default_client_factory(cfg)\n","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/etoro/client.py#L321-L357","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nreturn response.json()\n// after\ntry:\n    return response.json()\nexcept ValueError as exc:\n    raise EtoroAPIError(f\"invalid JSON response: {exc}\") from exc","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    data = client.request('GET', path)\nexcept EtoroAPIError as exc:\n    if 'invalid JSON response' in str(exc):\n        logger.error('non-JSON body from eToro: %s', exc)\n        raise","preventionTips":["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"],"tags":["etoro","json","http","api-response"],"backgroundTag":"invalid-json-response","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}