{"record":{"id":"f428bd143d4f180e","repo":"NousResearch/hermes-agent","slug":"gemini-stream-error","errorCode":"gemini_stream_error","errorMessage":"Gemini streaming request failed: {exc}","messagePattern":"Gemini streaming request failed: (.+?)","errorType":"exception","errorClass":"GeminiAPIError","httpStatus":null,"severity":"error","filePath":"agent/gemini_native_adapter.py","lineNumber":1088,"sourceCode":"        return translate_gemini_response(payload, model=model)\n\n    def _stream_completion(self, *, model: str, request: Dict[str, Any], timeout: Any = None) -> Iterator[_GeminiStreamChunk]:\n        url = f\"{self.base_url}/models/{model}:streamGenerateContent?alt=sse\"\n        stream_headers = dict(self._headers())\n        stream_headers[\"Accept\"] = \"text/event-stream\"\n\n        def _generator() -> Iterator[_GeminiStreamChunk]:\n            try:\n                with self._http.stream(\"POST\", url, json=request, headers=stream_headers, timeout=timeout) as response:\n                    if response.status_code != 200:\n                        body_text = read_streaming_error_body(response)\n                        raise gemini_http_error(response, body_text=body_text)\n                    tool_call_indices: Dict[str, Dict[str, Any]] = {}\n                    for event in _iter_sse_events(response):\n                        for chunk in translate_stream_event(event, model, tool_call_indices):\n                            yield chunk\n            except httpx.HTTPError as exc:\n                raise GeminiAPIError(\n                    f\"Gemini streaming request failed: {exc}\",\n                    code=\"gemini_stream_error\",\n                ) from exc\n\n        return _generator()\n\n\nclass AsyncGeminiNativeClient:\n    \"\"\"Async wrapper used by auxiliary_client for native Gemini calls.\"\"\"\n\n    def __init__(self, sync_client: GeminiNativeClient):\n        self._sync = sync_client\n        self.api_key = sync_client.api_key\n        self.base_url = sync_client.base_url\n        self.chat = _AsyncGeminiChatNamespace(self)\n        # Expose the underlying sync client as _real_client so the auxiliary\n        # cache's eviction-by-leaf-client helper (#23482) can find and drop\n        # this async entry when the sync GeminiNativeClient is poisoned.","sourceCodeStart":1070,"sourceCodeEnd":1106,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/gemini_native_adapter.py#L1070-L1106","documentation":"The streaming Gemini request (streamGenerateContent?alt=sse) failed with an httpx.HTTPError — connection error, timeout, or protocol-level failure during the SSE stream — before or while yielding chunks. It is wrapped in GeminiAPIError with code 'gemini_stream_error'. HTTP-status errors inside the stream are handled separately (gemini_http_error), so this code specifically means transport failure.","triggerScenarios":"Any httpx.HTTPError raised inside the stream generator: DNS/connect failure, connection reset mid-stream, read timeout while waiting for SSE events, TLS errors.","commonSituations":"Flaky network or VPN drops during long streaming generations; Google API transient resets; local firewall killing long-lived SSE connections; timeout configured too aggressively for slow generations.","solutions":["Retry the request — transient resets during long streams are common and usually succeed on retry.","Increase the client timeout passed to the adapter if failures cluster at a consistent elapsed time (timeout too small).","Check network stability (VPN/proxy) if streams consistently die mid-generation.","If persistent, capture the underlying httpx error message to distinguish connect vs read failures."],"exampleFix":"# caller-side retry for transient stream transport errors\nfrom agent.gemini_native_adapter import GeminiAPIError\n\nfor attempt in range(3):\n    try:\n        chunks = list(client.chat.completions.create(model=m, messages=msgs, stream=True))\n        break\n    except GeminiAPIError as e:\n        if e.code != \"gemini_stream_error\" or attempt == 2:\n            raise","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"from agent.gemini_native_adapter import GeminiAPIError\n\nfor attempt in range(3):\n    try:\n        chunks = list(client.chat.completions.create(model=m, messages=msgs, stream=True))\n        break\n    except GeminiAPIError as e:\n        if e.code != 'gemini_stream_error' or attempt == 2:\n            raise","preventionTips":["Retry transient stream transport failures once or twice before failing","Size timeouts for slow generations to avoid read timeouts mid-stream","Stabilize network (VPN/proxy) when streams consistently drop"],"tags":["gemini","streaming","network","retry"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}