xtekky/gpt4free · error · ResponseError

Gemini stream was idle for {idle_timeout:g} seconds

Error message

Gemini stream was idle for {idle_timeout:g} seconds

What it means

ResponseError raised by g4f/Provider/needs_auth/Gemini.py while reading the Gemini response stream: an asyncio.wait_for around each chunk read with idle_timeout expired, meaning no bytes arrived from the server for idle_timeout seconds. It guards against hangs when Gemini stalls (network drop, server-side pause) so callers see a definite error instead of an eternal await.

Source

Thrown at g4f/Provider/needs_auth/Gemini.py:230

async def _iter_response_lines(
    content,
    idle_timeout: float | None = None,
) -> AsyncIterator[str]:
    buffer = b""
    iterator = content.iter_any().__aiter__()
    while True:
        try:
            next_chunk = iterator.__anext__()
            chunk = (
                await asyncio.wait_for(next_chunk, timeout=idle_timeout)
                if idle_timeout is not None
                else await next_chunk
            )
        except StopAsyncIteration:
            break
        except asyncio.TimeoutError as exc:
            raise ResponseError(
                f"Gemini stream was idle for {idle_timeout:g} seconds"
            ) from exc
        buffer += chunk
        while b"\n" in buffer:
            line, buffer = buffer.split(b"\n", 1)
            yield line.decode("utf-8", errors="replace")
    if buffer:
        yield buffer.decode("utf-8", errors="replace")


def _resolve_model(model: str, think_override: int = None) -> tuple[str, bool]:
    requested_model = model
    think_mode = think_override
    if "@think=" in model:
        model, think_value = model.rsplit("@think=", 1)
        requested_model = model
        try:
            think_mode = int(think_value)

View on GitHub (pinned to 973504e177)

Solutions

  1. Increase the idle timeout (pass a larger idle_timeout value when calling the provider) to tolerate slow thinking models.
  2. Retry the request — transient stalls often succeed on a second attempt.
  3. Remove buffering proxies from the path or disable VPN for the streaming connection.
  4. Use a shorter max_tokens or split very long prompts to keep chunks flowing.

Example fix

# before
stream = Gemini.create_async_generator(model="gemini-2.5-pro", messages=msgs, idle_timeout=5)
# ResponseError: Gemini stream was idle for 5 seconds

# after
stream = Gemini.create_async_generator(model="gemini-2.5-pro", messages=msgs, idle_timeout=120)
Defensive patterns

Strategy: retry

Try / catch

from g4f.errors import ResponseError

async def gemini_stream_with_retry(model, messages, idle_timeout=60, retries=2):
    for i in range(retries + 1):
        try:
            return [c async for c in Gemini.create_async_generator(
                model=model, messages=messages, idle_timeout=idle_timeout)]
        except ResponseError as e:
            if "idle" not in str(e) or i == retries:
                raise
            idle_timeout *= 2

Prevention

When it happens

Trigger: Streaming a long Gemini response where the connection goes silent — e.g. extended thinking-mode pauses that exceed idle_timeout, flaky proxy/VPN dropping the socket, or Gemini server-side stall — for longer than the configured idle_timeout.

Common situations: Default idle timeout too small for slow reasoning models; mobile/unstable networks; corporate proxies that buffer then time out; very long generations with sparse keep-alive data.

Understand the failure class

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/c82f6ed431dc875c. Report an issue: GitHub.